给定一个包含 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]
]

分析:仿照 三数和的思路,再添加一个指针 固定
k i j h
看代码


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 length = nums.length;

       /*从这里开始,四个指针,k从0开始,i从k+1开始,留下jh,*/
       for(int k =0;k<length-3;k++){
           //去重
           if(k>0 && nums[k] == nums[k-1]){
               continue;
           }
            //当前最小值
           int min1 = nums[k]+nums[k+1]+nums[k+2]+nums[k+3];
           if(min1 > target){
               break;
           }
           //当前最大值
           int max1 = nums[k]+nums[length-1]+nums[length-2]+nums[length-3];
           if(max1 < target){
               continue;
           }

           //第二层循环
           for (int i = k+1; i <length-2 ; i++) {
                //去重
               if(i>k+1 && nums[i]==nums[i-1]){
                   //是k后面第二个开始
                   continue;
               }
               //指针j -> i+1
               int j = i+1;
               int h = length-1;

               int min2 = nums[k]+nums[i]+nums[j]+nums[j+1];
               if(min2 > target){
                   break;
               }
               int max2 = nums[k]+nums[i]+nums[h]+nums[h-1];
               if(max2 < target){
                   continue;
               }

               //开始j指针和h指针的表演
               while(j<h){
                   int curr=nums[k]+nums[i]+nums[j]+nums[h];
                   if(curr==target){
                       res.add(Arrays.asList(nums[k],nums[i],nums[j],nums[h]));
                       j++;
                       //去重
                       while(j<h&&nums[j]==nums[j-1]) j++;
                       h--;
                       while(j<h&&nums[h]==nums[h-1]) h++;
                   }else if(curr > target){
                       h--;
                   }else if(curr < target){
                       j++;
                   }
               }
           }
       }
       return res;
    }