1. 4Sum
    Medium

Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Notice that the solution set must not contain duplicate quadruplets.

Example 1:

Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Example 2:

Input: nums = [], target = 0
Output: []

Constraints:

0 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109

解法1:跟3Sum差不多。时间复杂度O(n^3),因为3sum时间复杂度是O(n ^2), 2sum时间复杂度是O(n)。
代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;

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

    sort(nums.begin(), nums.end());

    set<vector<int> > s;

    for (int i=0; i<nums.size()-3; ++i) {
        for (int j=i+1; j<nums.size()-2; ++j) {
            int diff2 = target-nums[i]-nums[j];
            int p1=j+1, p2=nums.size()-1;
            while(p1<p2) {
                int sum = nums[p1]+nums[p2];
                if (sum<diff2) p1++;
                else if (sum>diff2) p2--;
                else {
                     s.insert(vector<int>{nums[i], nums[j], nums[p1], nums[p2]});
                     p1++; p2--;   //do not directly break as there may be some other solutions left.
                }
            }
        }
    }

    for (auto it=s.begin(); it!=s.end(); ++it)   //note: should not use it<s.end() as set does not provide operator<
        vv.push_back(*it);

    return vv;
}

int main()
{
    //vector<int> S={1, 0, -1, 0, -2, 2};
    vector<int> S={-3,-2,-1,0,0,1,2,3};
    vector<vector<int> > vv;

    vv=fourSum(S, 0);

    cout<<"["<<endl;
    for (auto i : vv) {
        cout<<" [ ";
        for (auto j : i) cout<<j<<" ";
        cout<<"],"<<endl;
    }
    cout<<"]"<<endl;
    return 0;
}

要注意的地方有:

  1. 当找到一个解后,不要直接退出,还要p1++,p2–。因为可能还有其他解。
  2. set的iterator不支持operator<,只能用!=。这可能跟set内部是用RB tree有关,没法用<来判断。

解法2:把nums的元素两两相加,并记录(sum, pair(i, j)),这样就可以构成一个长度为n2n^2n2的数组,然后就可以直接用2sum了。时间复杂度是O(n2)O(n^2)O(n2)。下次做。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐