- 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;
}
要注意的地方有:
- 当找到一个解后,不要直接退出,还要p1++,p2–。因为可能还有其他解。
- set的iterator不支持operator<,只能用!=。这可能跟set内部是用RB tree有关,没法用<来判断。
解法2:把nums的元素两两相加,并记录(sum, pair(i, j)),这样就可以构成一个长度为n2n^2n2的数组,然后就可以直接用2sum了。时间复杂度是O(n2)O(n^2)O(n2)。下次做。