题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[ [-1, 0, 1],
[-1, -1, 2]
]
来源:力扣(LeetCode)
链接:https:
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
排序、双指针并去重;
思路详解
- 首先对当前数组进行排序,[-4,-1,-1,0,1,2]有序性有助于左右指针滑动是判断去重;
- 定义基点i(三数中数值最小,位置最左,单次循环内不滑动);
- 定义左指针left(三数中间位置数值)
- 定义右指针right(三数最右位置);
- 单轮循环中固定一个基点 i;
- 如果基点值大于0,则直接返回结果数组;(在有序数组中,如果当前基点值大于0,则后面的两数的任意组合必大于0)
- 防止基点重复;if(nums[i]===nums[i+1])则进入下一轮循环;
- 定义left=i+1;right=len-1;
- 固定基点,遍历寻找剩余两数的循环条件为(left<right)
- 如果sum===0;则防止left指针重复,条件为(left<right&&nums[left]===nums[left+1]); left++;
- 如果sum>0;则right--;
- 如果sum<0;则left++;
- 最后返回结果res数组;
代码
var threeSum = function(nums) {
let res=[],len=nums.length;
nums.sort((a,b)=>{ return a-b});
for(let i=0;i<len;i++){
if(nums[i]>0){
return res;
}
if(nums[i]===nums[i-1]){
continue;
}
let left=i+1;
let right=len-1;
while(left<right){
let sum=nums[i]+nums[left]+nums[right];
if(sum==0){
while(left<right&&nums[left]===nums[left+1]){
left++;
}
while(left<right&&nums[right]===nums[right-1]){
right--;
}
res.push([nums[i],nums[left],nums[right]]);
left++;
right--;
}else if(sum<0){
left++;
}else if(sum>0){
right--;
}
}
}
return res;
};