1. 程式人生 > >leetcode 四數之和

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;
    }
};