vector<vector<int>> twoSum(vector<int> &nums, int start, int target){
//思路,先进行排序,然后利用收尾双指针的方法获取值元素
//总的时间复杂度:排序 max(nlog(n), n) = nlog(n)
vector<vector<int>> res;
if(nums.size() < 2) return res;
sort(nums.begin(), nums.end());
int i = start, j = nums.size() - 1;
while(i < j){
int a = nums[i], b = nums[j];
int c = a + b;
if(c < target) while(++i < j && nums[i] == a);
else if(c > target) while(--j > i && nums[j] == b);
else{
//符合条件,保存结果
vector<int> v{a, b};
res.push_back(v);
//结果去重
while(++i < j && nums[i] == a);
while(--j > i && nums[j] == b);
}
}
return res;
}
vector<vector<int>> threeSum(vector<int> &nums, int target){
//思路可以利用 twoSum 的结果,时间复杂度 n^2
vector<vector<int>> res;
if(nums.size() < 3) return res;
sort(nums.begin(), nums.end());
while(i < nums.size()){
int a = nums[i];
vector<vector<int>> t = twoSum(nums, i + 1, target - a); //注意函数里面去掉sort排序
for(auto v:t){
v.push_back(a);
res.push_back(v);
}
while(++i < nums.size() && nums[i] == a);
}
return res;
}
vector<vector<int>> nSum(vector<int>& nums, int start, int n, long target) {
//回头看看 3sum 利用 2sum的关系,应该可以用递归来实现 nSum 的问题
//调用该函数前,需要先调用sort对nums排序
vector<vector<int>> res;
if(start < 0 || start >= nums.size() || n < 2 || n > nums.size()){
return res;
}
int i = start, j = nums.size() - 1;
if(n == 2) {
//递归返回条件
while(i < j) {
int a = nums[i], b = nums[j];
int c = a + b;
if(c < target){
while(++i < j && nums[i] == a);
}else if(c > target){
while(--j > i && nums[j] == b);
}else {
vector<int> v{a, b};
res.push_back(v);
while(++i < j && nums[i] == a);
while(--j > i && nums[j] == b);
}
}
}else{
//递归手法
int k = start;
while(k < nums.size()){
int a = nums[k];
vector<vector<int>> v = nSum(nums, k + 1, n - 1, target - a);
for(auto &elem : v){
elem.push_back(a);
res.push_back(elem);
}
while(++k < nums.size() && nums[k] == a); //去重不要忘记
}
}
return res;
}
调用:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
return nSum(nums, 0, 4, target);
}