Leetcode 15. 三数之和解法
题面及样例输入输出:
题目来源:leetcode(力扣)
链接:https://leetcode-cn.com/problems/3sum/
特别要注意的是不可以包含重复的三元组,即需要进行去重操作。
回溯写法:
class Solution {
private:
vector<vector<int>>res;
vector<int>path;
void backtracking(vector<int>&nums,int n,int startindex,int sum)
{
if(n == 3)
{
if(sum == 0)
res.push_back(path);
return;
}
for(int i = startindex; i < nums.size(); i++)
{
if(i != startindex && nums[i] == nums[i-1])
continue;
sum += nums[i];
path.push_back(nums[i]);
backtracking(nums,n+1,i+1,sum);
path.pop_back();
sum -= nums[i];
}
}
public:
vector<vector<int>> threeSum(vector<int>& nums) {
if(nums.size() < 3)
return res;
sort(nums.begin(),nums.end());
backtracking(nums,0,0,0);
return res;
}
};
但可惜的是,并没有通过leetcode所有上的测试用例,因为回溯需要不断递归,所以容易超时,这是回溯的缺点。
后面参考评论,改用双指针的方法,代码如下:
双指针写法:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>result;
vector<int>path(3);
sort(nums.begin(),nums.end());
for(int i = 0; i < nums.size(); i++)
{
if(nums[0] > 0 || nums.size() < 3)//特殊情况直接返回空值
return result;
if(i > 0 && nums[i] == nums[i-1])//去重
continue;
int l = i+1, r = nums.size()-1;//双指针
while(l < r)
{
int sum = nums[i] + nums[l] + nums[r];
if(sum == 0) {
path[0] = nums[i];
path[1] = nums[l];
path[2] = nums[r];
result.push_back(path);
while(l < r && nums[l] == nums[l+1])//左边界去重
l++;
while(l < r && nums[r] == nums[r-1])//右边界去重
r--;
l++;r--;
}
else if(sum < 0)//sum值小于0,左边界往右移
l++;
else if(sum > 0)//sum值大于0,右边界往左移
r--;
}
}
return result;
}
};