[LeetCode-Medium Question] 18. Sum of four numbers

topic

Insert image description here

Method 1: Double pointers (fixed 2 moving 2)

This question can refer to [LeetCode-Medium Question] 15. The difference between the sum of three numbers
is that the sum of three numbers only needs to use a for loop to fix a number, and then set two front and rear pointers to slide based on the comparison between the sum value and the target value. pointer

Then this question is the same. What we need to do is to fix two numbers. We need to use two for loops to fix the two numbers, and then set two front and rear pointers to slide the pointer based on the comparison between the sum value and the target value.

There are many processing details that need to be paid attention to. Some situations where it is impossible to meet the conditions should be handled in advance to reduce time complexity.
Insert image description here

class Solution {
    
    
//for定2 指针动2
    public List<List<Integer>> fourSum(int[] nums, int target) {
    
    
      int len =  nums.length;
      if(nums == null||len < 4 ) return new ArrayList<>();
      List<List<Integer>> res = new ArrayList<>();
      List<Integer> zres = null;
      Arrays.sort(nums);
      for(int i = 0 ;i< len-3 ;i++){
    
    
           //本身就是排序的数组  若第一个数就大于等于target了那么再加上任何一个数都会大于target,所以直接break
        //    if(nums[i]>target)  break;
        //这个条件不能要(对比LeetCode 15. 三数之和)  如果target是负数,第一个数大于target  在往下加可能会越来越小也是可以=taget的
                                     //但是如果target为0或正数,那么第一个数大于target  往下加会越来越大
          //去重操作  如果nums[i]==nums[i-1] 会得到一份与nums[i-1]一样的结果集
          if(i>0&&nums[i]==nums[i-1]) continue;
           // 若以i开头的四个元素就已经大于target了 那就无需做任何操作了,没必要了,在往后面加再怎么也会大于target
          if((long)nums[i]+nums[i+1]+nums[i+2]+nums[i+3] > target) break;
          // 若以i开头元素和数组末尾的三个元素就还小于target了 那就没必要做此次循环,毕竟i加上后面最大的三个数都比target小
          if((long)nums[i]+nums[len-1]+nums[len-2]+nums[len-3] < target) continue;
          for(int j = i+1 ;j< len-2 ;j++){
    
    //这里就和 LeetCode 15. 三数之和  一样的原理  唯一多了一个提前判断
              // 这里的三个if与上面同理  
               if(j>i+1&&nums[j]==nums[j-1]) continue;
               if((long)nums[i]+nums[j]+nums[j+1]+nums[j+2] > target) break;
               if((long)nums[i]+nums[j]+nums[len-1]+nums[len-2] < target) continue;
               int left = j+1;
               int right = len-1;
               while(left < right){
    
    
                   long sum =(long) nums[i]+nums[j]+nums[left]+nums[right];
                   if(sum == target) {
    
    
                       zres = new ArrayList<>();//满足要求的子结果集
                       zres.add(nums[i]);
                       zres.add(nums[j]);
                       zres.add(nums[left]);
                       zres.add(nums[right]);
                       res.add(zres);//加入大结果集
                       while(left < right &&nums[left]==nums[left+1]) left++;//两个指针的去重
                       while(left < right &&nums[right]==nums[right-1]) right--;
                       left++;//移动指针到不重复的新区域
                       right--;
                   }else if(sum >target)  right--;//缩小数值
                    else left++;//扩大数值
               }
          }
      }
      return res;
    }
}

Guess you like

Origin blog.csdn.net/weixin_45618869/article/details/132871360