思路
这道题目我们可以采用双指针的做法,我们设定了一个i用作第一个元素的遍历,然后设计left=i+1、right=nums[nums.length-1],然后计算target = nums[i]+nums[left]+nums[right],如果target>0,那么right--;如果target<0,那么left++;如果target==0,那么得到了结果。
思路不是特别难,但是这道题目需要考虑的就是去重的逻辑。
对于i的去重,我们有两个考虑,第一个是判断nums[i]==nums[i+1],第二个是判断nums[i]==nums[i-1]。当考虑到如果存在数组{-1,-1,2}的时候,如果我们使用第一种判断,那么就得不到正确的值,第一种判断等于让i和left进行了一次判断,所以我们需要使用第二种判断,判断以前遍历过的值,不要判断未来没有遍历过的值。
此外,我们还需要考虑left和right的去重,那么我们就需要判断nums[left]==nums[left+1]和nums[right]==nums[right-1],判断left和right与未来的值是否相等,如果相等,那么就需要去重,也就是left++和right--,因为本身再找到答案之后就需要left++和right--,所以可以这么去重。
代码
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(nums[i]>0) return result;
if(i>0 && nums[i]==nums[i-1]) continue;
int left=i+1;
int right=nums.length-1;
while(left<right){
int target = nums[i]+nums[left]+nums[right];
if(target>0)
right--;
else if(target<0)
left++;
else if(target==0){
result.add(Arrays.asList(nums[i],nums[left],nums[right]));
while(left<right && nums[left]==nums[left+1]) left++;
while(left<right && nums[right]==nums[right-1]) right--;
left++;
right--;
}
}
}
return result;
}
}