leetcode 四数之和

题目描述:

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

解题思路: 

先排序,在定四个索引: a, b, c, d;  其中a, b依次从头到尾开始遍历,c定在b+1,d定在nums.size()-1, 然后c, d慢慢靠拢。如果nums[a] + nums[b] + nums[c] + nums[d] > target,在前面基数a,b固定的情况下,则只能移动d--,才能使和变小,才有可能找到相等的索引,反之如果<target,则只能c++

C++代码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;  // 二维数组
        int N=nums.size();
        if(N<4) return result;
        sort(nums.begin(),nums.end()); // 先排序
        
        for(int a=0;a<N-3;a++){ // a = n-4, b = n-3, c = n-2, d = n -1 
            if(a>0 && nums[a]==nums[a-1])continue; //跳过重复
            if(nums[a]+nums[a+1]+nums[a+2]+nums[a+3]>target)break;//太大了
            if(nums[a]+nums[N-3]+nums[N-2]+nums[N-1]<target)continue;//太小了,以当前a为基
            
            for(int b=a+1;b<N-2;b++){ // b= n-3, c = n-2, d = n -1 
                if(b>a+1 && nums[b]==nums[b-1])continue;//跳过重复
                if(nums[a]+nums[b]+nums[b+1]+nums[b+2]>target)break;//太大了
                if(nums[a]+nums[b]+nums[N-2]+nums[N-1]<target)continue;//太小了,以当前a,b为基
                
                int c=b+1,d=N-1; // 以a,b为基,c指向首,d指向尾,然后c、d逐渐靠拢
                while(c<d){
                    int sum=nums[a]+nums[b]+nums[c]+nums[d];
                    if(sum>target){
                        d--;
                        while(c<d && nums[d]==nums[d+1]) d--;//跳过重复
                    }else if(sum<target){
                        c++;
                        while(c<d && nums[c]==nums[c-1]) c++;//跳过重复
                    }else{
                        result.push_back({nums[a],nums[b],nums[c],nums[d]});//得到一个解
                        d--;
                        while(c<d && nums[d]==nums[d+1]) d--;//跳过重复
                        c++;
                        while(c<d && nums[c]==nums[c-1]) c++;//跳过重复
                    }
                }
            }
        }

        return result;
    }
};

猜你喜欢

转载自blog.csdn.net/jizhidexiaoming/article/details/84335181