1. 程式人生 > >【Leetcode】【4Sum】【四數之和】【C++】

【Leetcode】【4Sum】【四數之和】【C++】

leetcode 元祖 tor sort 4sum 註意 元素 return 解決

  • 題目:給定一個整數數組nums和一個目標值target,判斷是否存在四個數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] ]

  • 說明: 註意找出的四元組不重合,即沒有相同的四元組;且四元組按從小到大的順序輸出。
  • 思路1:對nums數組排序,然後兩個for循環遍歷,獲取兩個數組元素,在剩余元素中找出兩個數,這兩個數與之前兩個數組元素的和為targe。(註意,可能剩余元素中滿足要求的兩個數不止一對,如target=9,for循環獲取到的兩個數是1,2 那麽就要在剩余元素中找出和為6的兩個數,如果剩余元素為2,3,3,4,那麽滿足要求的有[2,4] 和[3,3])(另外,還要註意兩個for循環遍歷的兩個元素不能有相同,這樣也會造成重復)
  • 代碼:
  • class Solution {
    public:
        vector<vector<int> > fourSum(vector<int>& nums, int target) {
            vector<vector<int> > res;
            sort(nums.begin(),nums.end());
            int len=nums.size();
            for(int i=0; i<len; i++)
            {
                if(i!=0 && nums[i]==nums[i-1
    ]) continue; //判斷nums[i]是否和上次一個(如果有的話)相等 for(int j=i+1; j<len; j++) { if(j!=(i+1) && nums[j]==nums[j-1]) { continue;//作用類似於上面的if語句,判斷是否重復 } vector<vector<int> >sum2;
    int temTarg= target-nums[i]-nums[j]; int left=j+1,right=len-1; int lastleftval=-1,lastrightval=-1; bool flag=false; while(left<right) { if(left ==i || left==j) { left++; continue; } if(right==i || right==j) { right--; continue; } if((nums[left]+nums[right])==temTarg)//此處,可能有不止一對滿足條件的結果,故找到後不能簡單得用break語句跳出循環 { if(flag==true && nums[left]==lastleftval && nums[right]==lastrightval) { left++; right--; continue; } flag=true; lastleftval=nums[left]; lastrightval=nums[right]; vector<int>subsum2; subsum2.push_back(nums[left]); subsum2.push_back(nums[right]); sum2.push_back(subsum2); left++; right--; } else if((nums[left]+nums[right])>temTarg) { right--; } else { left++; } } int lensum2=sum2.size(); for(int k=0; k<lensum2; k++) { vector<int>temp; temp.push_back(nums[i]); temp.push_back(nums[j]); temp.push_back(sum2[k][0]); temp.push_back(sum2[k][1]); res.push_back(temp); } } } return res; } };

  • 思路2:遞歸解決(使用於求k個數之和的情況,這種方法更普遍),將求k數之和轉換為求k-1數之和,直到k=2
  • 代碼:
  • class Solution {
        vector<vector<int> > kSum(vector<int>& nums, int start, int k, int target)
        {
            vector<vector<int> > res;
            int len=nums.size();
            if(k==2)
            {
                int left=start,right=len-1;
                int lastleftval=-1,lastrightval=-1;
                bool flag=false;// flag=false表示還未滿足條件的元祖
                while(left<right)
                {
                    if((nums[left]+nums[right])>target)
                        right--;
                    else if((nums[left]+nums[right])<target)
                        left++;
                    else
                    {
                        if(flag==true && lastleftval==nums[left] && lastrightval==nums[right])
                        {
                            left++;
                            right--;
                            continue;
                        }
                        flag=true;
                        lastleftval=nums[left];
                        lastrightval=nums[right];
                        vector<int> subres;
                        subres.push_back(nums[left]);
                        subres.push_back(nums[right]);
                        res.push_back(subres);
                        left++;
                        right--;
                    }
                }
                return res;
            }
            int lastval=-1;
            for(int i=start; i<len; i++)
            {
                if(i!=start && nums[i]==nums[i-1])
                    continue;
                vector<vector<int> > subres= kSum(nums, i+1, k-1, target-nums[i]);
                int sublen=subres.size();
                for(int j=0; j<sublen; j++)
                {
                    vector<int>temp;
                    temp.push_back(nums[i]);
                    for(int j1=0; j1<k-1; j1++)
                        temp.push_back(subres[j][j1]);
                    res.push_back(temp);
                }
            }
            return res;
        }
    public:
        vector<vector<int> > fourSum(vector<int>& nums, int target) {
            vector<vector<int> > res;
            int len=nums.size();
            if(len==0)
                return res;
            sort(nums.begin(),nums.end());
            return kSum(nums,0,4,target);
        }
    };

【Leetcode】【4Sum】【四數之和】【C++】