题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
提示:
- 0 <= nums.length <= 3000
- 1 0 5 10^5 105 <= nums[i] <= 1 0 5 10^5 105
解法
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int len = nums.size();
if(len < 3) return {}; //特判
vector<vector<int>> ans; //返回结果
std::sort(nums.begin(),nums.end()); //默认是升序
for(int a = 0 ; a < len;a++) //固定第一个,后面两个用双指针
{
if (nums[a] > 0) return ans; //排序好后,第一个大于0,最后三数之和不可能等于0 ,第二次判特
if(a > 0 && nums[a] == nums[a-1]) //去重
{
continue;
}
int b = a + 1; //左指针
int c = len - 1; //右指针
while(b < c) //使用双指针,选最大容器的题目刚使用了这个算法
{
if(nums[b] + nums[c] > -nums[a])
{
c--; //数太大了
}
else if(nums[b] + nums[c] < -nums[a])
{
b++; //数太小了,左指针右移
}
else{ //正好等于0
ans.push_back(vector<int>{nums[a],nums[b],nums[c]});
b++;
c--;
//双指针缩小空间时,也需要考虑去重
// 例如:[-4,1,1,1,2,3,3,3], i=0, left=1, right=5
while((b < c) && nums[b] == nums[b-1]) b++; //左去重
while((b < c) && nums[c] == nums[c+1]) c--; //右去重
}
}
}
return ans;
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。