Leetcode -- 4Sum

题目:
Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:
Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)
The solution set must not contain duplicate quadruplets.
For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
A solution set is:
(-1, 0, 0, 1)
(-2, -1, 1, 2)
(-2, 0, 0, 2)

分析:
数组,找到四个数,使得其和等于target。

思路:
排序,遍历。将4Sum处理成3Sum,再根据3Sum的求解方法即可。

代码:

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int> > result;
        vector<vector<int> > arr;
        int sum, len = nums.size();
        if(len < 4)  return result;
        sort(nums.begin(), nums.end());
        for(int i =0; i< len - 3; i++)
        {
            if( i == 0 || nums[i - 1] != nums[i])
            {
                sum = target - nums[i];
                arr = threeSum(nums, sum, i+1);
                if(arr.size() != 0)
                {
                    for(int j =0; j< arr.size(); j++)
                    {
                        result.push_back({nums[i], arr[j][0], arr[j][1], arr[j][2]});
                    }
                }
            }
        }
        return result;
    }

    vector<vector<int>> threeSum(vector<int>& nums, int tt, int start) {
     vector <vector<int> > result;
       int len = nums.size();
       int front, back, sum, target;

       for(int i = start; i< len; i++)
       {
           front = i + 1;
           back = len -1;
           target = tt -nums[i];
           while(front < back)
           {
              sum = nums[front] + nums[back];
              if(sum < target) front ++;
              if(sum > target) back --;
              if(sum == target)
              {
                  vector<int> arr(3, 0);
                  arr[0] = nums[i];
                  arr[1] = nums[front];
                  arr[2] = nums[back];
                  result.push_back(arr);

                  while(nums[front] == arr[1] && front<back) front ++;
                  while(nums[back] == arr[2] && front < back) back --;
              }
           }
           while((i+1)<len && nums[i+1] == nums[i])
           {
               i = i+ 1;
           }
       }
       return result;
    }
};

参考Discussion
思路:
hashtable。
The idea is to sort nums first, then build a hashtable with the key as the sum of the pair and the value as a vector storing all pairs of index of num that having the same sum. In this way, all elements stored in hashtable has a order that duplicate pairs are neighbors. Therefore scanning the vector in the hashtable we only put non duplicate elements into the final answer .

代码:

 class Solution{ //using hashtable, avg O(n^2)

public:

    vector<vector<int> > fourSum(vector<int> &nums, int target){
        vector<vector<int> > vvi;
        int n = nums.size();
        if(n < 4) return  vvi;

        sort(nums.begin(), nums.end());        
        unordered_map<int, vector<pair<int, int>> > mp;
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
                mp[nums[i]+nums[j]].push_back(make_pair(i,j));
            }
        }

        for(int i = 0; i < n; i++){
            if(i>0 && nums[i] == nums[i-1]) continue;
            for(int j = i + 1; j < n; j++){
                if(j > i + 1 && nums[j] == nums[j-1]) continue;
                int res = target - nums[i] - nums[j];
                if(mp.count(res)){
                    for(auto it = mp[res].begin(); it != mp[res].end(); it++){
                        int k = (*it).first, l = (*it).second;
                        if(k > j){ // k>j make sure that the second pair has bigger values than the first pair.
                            if(!vvi.empty() && nums[i]==vvi.back()[0] && nums[j]==vvi.back()[1]
                            && nums[k]==vvi.back()[2] && nums[l] == vvi.back()[3]){
                                continue; //if the obtained 4 elements are the same as previous one continue to next
                            }
                            vector<int> vi={nums[i], nums[j], nums[k], nums[l]};
                            vvi.push_back(vi);
                        }

                    }
                }
            }
        }
        return vvi;
    }
  };

PS: 3Sum也是可以用hashtable求解的哦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值