题目链接
Merge Two Sorted Lists - LeetCode
注意点
- 和3Sum那道题一样
解法
解法一:在3Sum的基础上再加一层循环即可。时间复杂度为O(n^3)
class Solution {
public:
using num_t = vector<int>;
vector<vector<int>> fourSum(vector<int>& nums, int target) {
int n = nums.size(),newTarget,i = n-1,j,l,r;
vector<num_t> ans;
if(n < 4) return ans;
sort(nums.begin(),nums.end());
while(i >= 3)
{
newTarget = target - nums[i];
j = i-1;
while(j >= 2)
{
l = 0;
r = j-1;
while(l < r)
{
int sum = nums[l]+nums[r]+nums[j];
if(sum < newTarget) l++;
else if(sum > newTarget) r--;
else
{
ans.push_back({nums[i],nums[j],nums[l],nums[r]});
l++;
r--;
while (l<r && nums[l-1]==nums[l]) l++;
while (l<r && nums[r+1]==nums[r]) r--;
}
}
j--;
while(j >= 2 && nums[j+1]==nums[j]) j--;
}
i--;
while(i >= 3 && nums[i+1]==nums[i]) i--;
}
return ans;
}
};
解法二:看了评论得到的思路。先二重循环,将所有可能出现的两数之和的值map保存。然后再二重循环,计算两数之和,比较加上map中存的值之后是否等于target。时间复杂度为O(n^2)
class Solution {
public:
using num_t = vector<int>;
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<num_t> ret;
int n = nums.size(),i,j;
if(n < 4) return ret;
unordered_map<int,vector<pair<int,int>>> myMap;
for(i = 0;i < n;i++)
{
for(j = i+1;j < n;j++)
{
myMap[target - nums[i] - nums[j]].push_back({i,j});
}
}
for(i = 0;i < n;i++)
{
for(j = i+1;j < n;j++)
{
int temp = nums[i] + nums[j];
if(myMap.count(temp))
{
for(auto p:myMap[temp])
{
if(p.first != i && p.first != j && p.second != i && p.second != j)
{
ret.push_back({nums[p.first],nums[p.second],nums[i],nums[j]});
}
}
}
}
}
n = ret.size();
for(i = 0;i < n;i++)
{
sort(ret[i].begin(),ret[i].end());
}
sort(ret.begin(),ret.end());
ret.erase(unique(ret.begin(),ret.end()),ret.end());
return ret;
}
};
注:虽然这道题时间复杂度为O(n2)但是去重所花的时间过多,导致最终所花时间甚至高于O(n3)
再注:去重所花时间是固定的,取决于输入的数组长度。所以在求nSum的问题的时候,随着n的增大,解法二更有优势。
小结
- unique函数
- map中key对应的value是唯一的,如果想一个key对应多个value可以像解法二一样,构造一个
map<int,vector<int>>