LeetCode 18. 四数之和

​ 本题使用双指针解法,代码如下

class Solution {
        public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);

        for (int i = 0; i < nums.length; i++) {
            if(nums[i] > target && target > 0) return res;
            if(i > 0 && nums[i] == nums[i - 1]) continue;

            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] > target && target > 0) break;
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
            
                int l = j + 1, r = nums.length - 1;
                while (l < r) {
                    long sum = (long) nums[i] + nums[j] + nums[l] + nums[r];
                    if (sum > target) {
                        r --;
                    }else if (sum < target) {
                        l ++;
                    }else {
                        res.add(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
                        while (r > l && nums[r] == nums[r - 1]) r--;
                        while (r > l && nums[l] == nums[l + 1]) l++;
                        
                        r --;
                        l ++;
                    }
                }
            }
        }
        return res;
    }
}

先将nums数组排序后遍历,其中需要注意如下几点

  1. for.i循环中判断是否跳出循环的条件: nums[i] > target && target > 0,因为存在负数可能(如: -5, -4, -3 , -2, -1, 0; target = -8,-5 > -8,但实际上是存在满足可能的),所以target必须大于0时才能判断

  2. for.j循环中跳出循环使用break: 在遍历过程中有可能存在i, j指针中间存在满足条件的元素,但如果return res,会直接跳过该答案,如图:
    .
    在这里插入图片描述
    ​ 当前nums[i] + nums[j] > target,但红色部分存在元素满足target,所以必须使用break跳出循环,而不是return返回res数组

  3. r, l的去重,r 与 r - 1对比,因为当r = nums.length - 1时,为最右端元素,需要向左去重遍历,l同理向右遍历

  4. 注意去重之后r, l分别需要前进一位,因为当前r, l所指向的是最后一个重复元素,且该元素已经被添加到res中,所以需要再向前进一位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值