题目描述
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c,使得
a + b + c = 0
?找出所有满足条件且不重复的三元组。注意:答案中不可以包含
重复的三元组
样例
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
注意:
根据样例可以看出答案的子集内部
可以有重复,子集间
不能有重复
思路
朴素想法,三重枚举,然后去重
但借鉴 相似题目 有序数组求两数之和为定值
的思路,我们可以先对数组排序,再利用首位双指针来寻找答案
算法
排序 + 判重 + 双指针
- 对数组排序
- 无重复的枚举第一个数
- 利用双指针无重复的寻找另外2个数
c++代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(), nums.end());
for(int st = 0; st < nums.size(); st ++){
while( st && st < nums.size() && nums[st - 1] == nums[st])
st ++;
int l = st + 1, r = nums.size() - 1;
while(l < r)
{
if(nums[st] + nums[l] + nums[r] == 0 )
{
res.push_back({nums[st], nums[l], nums[r]});
do l ++; while (l < r && nums[l] == nums[l - 1]);
do r --; while (l < r && nums[r] == nums[r + 1]);
}
else if( nums[st] + nums[l] + nums[r] < 0)
{
do l ++; while (l < r && nums[l] == nums[l - 1]) ;
}
else
{
do r --; while (l < r && nums[r] == nums[r + 1]);
}
}
}
return res;
}
};
小结
- 有序数组,有重复元素,如何寻找改元素第一次出现的位置和最后一次出现的位置??
while( st && st < nums.size() && nums[st - 1] == nums[st])
改为while( st < nums.size() && nums[st + 1] == nums[st])
这样则答案内部也不能有重复的 如
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
]