【双指针】18. 四数之和

题目:

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:

答案中不可以包含重复的四元组。

示例:

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]

 

解答:

方法一:排序+双指针

 

注意点:

  • 每一种循环枚举到的下标必须大于上一重循环枚举到的下标;

  • 同一重循环中,如果当前元素与上一个元素相同,则跳过当前元素。

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        
        if(nums==null||nums.length<4){
            return res;
        }

        Arrays.sort(nums);
        int n = nums.length;
        for(int i = 0;i<n-3;i++){
            //同一重循环中,如果当前元素与上一个元素相同,则跳过当前元素。
            if(i>0&&nums[i]==nums[i-1]){
                continue;
            }
            if(nums[i]+nums[i+1]+nums[i+2]+nums[i+3] >target){
                break;
            }
            if(nums[i]+nums[n-3]+nums[n-2]+nums[n-1]<target){
                continue;
            }

            for(int j = i+1;j<n-2;j++){
                //同一重循环中,如果当前元素与上一个元素相同,则跳过当前元素。
                if(j>i+1 && nums[j]==nums[j-1]){
                    continue;
                }

                if(nums[i]+nums[j]+nums[j+1]+nums[j+2]>target){
                    break;
                }
                if(nums[i]+nums[j]+nums[n-2]+nums[n-1]<target){
                    continue;
                }

                int sum = nums[i] + nums[j];
                
                int curTarget = target-sum;
                int l = j+1,r = n-1;
                while(l<r){

                    if(nums[l]+nums[r] == curTarget){
                        res.add(Arrays.asList(nums[i], nums[j], nums[l],nums[r]));
                        //同一重循环中,如果当前元素与上一个元素相同,则跳过当前元素。
                        while(l<r&&nums[l]==nums[l+1]){
                            l++;
                        }
                        l++;
                        //同一重循环中,如果当前元素与上一个元素相同,则跳过当前元素。
                        while(l<r&&nums[r]==nums[r-1]){
                            r--;
                        } 
                        r--;
                    }
                    else if(nums[l]+nums[r]>curTarget){
                        r--;
                    }else{
                        l++;
                    }
                    
                }
            }
        }

        return res;
    }
}

 

posted @ 2020-10-25 23:57  3KBLACK  阅读(90)  评论(0)    收藏  举报