题目
代码(首刷看解析)
这类型的题都可以用递归实现,可以实现n数之和。
18. 四数之和同理。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nSum(nums, 0, 0, 3);
}
vector<vector<int>> nSum(vector<int>& nums, int start, int target, int n) {
vector<vector<int>> res;
int sz = nums.size();
if(sz < n || n < 2)
return res;
if(n == 2) {
int low = start, high = sz - 1;
while(low < high) {
int left = nums[low], right = nums[high];
if(left + right == target) {
res.push_back({left, right});
while(low < high && left == nums[low]) low++;
while(low < high && right == nums[high]) high--;
} else if(left + right < target) {
while(low < high && left == nums[low]) low++;
} else {
while(low < high && right == nums[high]) high--;
}
}
} else { // 递归
for(int i = start; i < sz; i++) {
auto sub = nSum(nums, i+1, target - nums[i], n-1);
for(auto& arr : sub) {
arr.push_back(nums[i]);
res.push_back(arr);
}
while(i+1<sz && nums[i] == nums[i+1]) i++;
}
}
return res;
}
};
代码(8.23 二刷部分看解析)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& num) {
sort(num.begin(), num.end());
return nSum(num, 0, 0, 3);
}
vector<vector<int>> nSum(vector<int>& nums, int start, int target, int n) {
vector<vector<int>> res;
if(n == 2) {
int left = start, right = nums.size()-1;
while(left < right) {
int low = nums[left], high = nums[right];
int count = nums[left] + nums[right];
if(count == target) {
res.push_back({nums[left], nums[right]});
while(left < right && low == nums[left]) left++;
while(left < right && high == nums[right]) right--;
} else if(count < target) {
while(left < right && low == nums[left]) left++;
} else {
while(left < right && high == nums[right]) right--;
}
}
} else {
for(int i = start; i < nums.size(); i++) {
auto tmp = nSum(nums, i+1, target-nums[i], n-1);
for(auto& sub : tmp) {
// cout<<sub[0]<<endl;
sub.insert(sub.begin(), nums[i]);
res.emplace_back(sub);
}
while(i+1 < nums.size() && nums[i] == nums[i+1])
i++;
}
}
return res;
}
};
代码(9.5 三刷自解)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nSum(nums, 0, 0, 3);
}
vector<vector<int>> nSum(vector<int>& nums, int start, int sum, int k) {
if(k == 2) {
vector<vector<int>> ans;
int l = start, r = nums.size()-1;
while(l < r) {
int left = nums[l], right = nums[r];
int count = nums[l]+nums[r];
if(count < sum) {
while(l < r && nums[l] == left)
l++;
} else if(count > sum) {
while(l < r && nums[r] == right)
r--;
} else {
ans.push_back({nums[l], nums[r]});
// cout<<nums[l]<<" "<<nums[r]<<endl;
while(l < r && nums[l] == left) l++;
while(l < r && nums[r] == right) r--;
}
}
return ans;
}
vector<vector<int>> ans;
for(int i = start; i < nums.size(); i++) {
auto str = nSum(nums, i+1, sum-nums[i], k-1);
for(auto& sub : str) {
sub.emplace_back(nums[i]);
ans.emplace_back(sub);
}
while(i+1 < nums.size() && nums[i+1] == nums[i]) i++;
}
return ans;
}
};
代码(9.22 四刷自解)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
return nSum(nums, 3, 0, 0);
}
vector<vector<int>> nSum(vector<int>& nums, int n, int sum, int k) {
vector<vector<int>> ans;
if(n == 2) {
int left = k, right = nums.size()-1;
while(left < right) {
int l = nums[left], r = nums[right];
int count = l+r;
if(count < sum) {
while(left < right && nums[left] == l) left++;
} else if(count > sum) {
while(left < right && nums[right] == r) right--;
} else {
ans.push_back({l, r});
while(left < right && nums[left] == l) left++;
while(left < right && nums[right] == r) right--;
}
}
} else {
for(int i = k; i < nums.size(); ++i) {
auto sub = nSum(nums, n-1, sum-nums[i], i+1);
for(auto& arr : sub) {
arr.emplace_back(nums[i]);
ans.push_back(arr);
}
while(i+1 < nums.size() && nums[i] == nums[i+1]) i++;
}
}
return ans;
}
};