1.题目链接
2.题目描述
算法
本题的难点在于如何去除重复解。
算法流程:
复杂度分析
双指针法:
类似2sum, 不过是这次是求和为 - nums[i]的两个数.
先对数组进行排序(增序), 双指针从两侧遍历, 若和大于-nows[i], 右指针向左走,否则左指针向右走.
为什么大于时不是左指针向左走呢? 因为左指针相对于右指针更靠近开头, 如果左指针向左走, 容易碰到now元素(low和high始终都在now的后面)而结束, 所以为了效率让右指针向左走. 小于情况相同.
注意重复的情况要去重.
代码
Python3
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
res = []
if(not nums or n<3):
return []
nums.sort()
res = []
for i in range(n):
if(nums[i] > 0):
return res
if(i>0 and nums[i]==nums[i-1]):
continue #跳过
L = i + 1
R = n - 1
while(L<R):
if(nums[i] + nums[L] + nums[R]==0):
res.append([nums[i],nums[L],nums[R]])
#去重,待定数不变找下一个答案
while(L<R and nums[L]==nums[L+1]):
L = L + 1
while(L<R and nums[R] == nums[R-1]):
R = R + 1
L = L + 1
R = R - 1
elif(nums[i] + nums[L] + nums[R] > 0):
R = R - 1
else:
L = L + 1
return res #对齐
C++
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums)
{
int N = nums.size();
if(N < 3)
return {};
const int target = 0;
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for(int i = 0; i < N - 2; ++i)
{
if(nums[i] > target)
break;
if(i > 0 && nums[i] == nums[i - 1])
continue;
int left = i + 1, right = N - 1;
while(left < right)
{
if(nums[i] + nums[left] + nums[right] == target)
{
res.push_back({nums[i], nums[left], nums[right]});
cout << nums[i] << " " << nums[left] << " " << nums[right] << endl;
while(left < right && nums[left + 1] == nums[left])
left++;
while(left < right && nums[right - 1] == nums[right])
right--;
left++;
right--;
}
else if(nums[i] + nums[left] + nums[right] > target)
right--;
else
left++;
}
}
return res;
}
};
将res在函数外全局定义, 能减少内存.