LeetCode 三数之和 Java 双指针

题目描述
给你一个包含 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://leetcode-cn.com/problems/3sum

思路:

1.特殊情况判断当数组长度小于3,直接返回new ArrayList();

2.用双指针之前将数组排序,不然双指针没法使用;

3.1 选取一个点i表示a的位置,然后用left和right
分别表示b和c的位置,left应该在i后面,所以left
的初始值为i+1,right就放在数组最后面,在判断过
程中两头缩进;

3.2 在选取i的时候从前往后找,如果nums[i]>0可
以直接退出循环,if(i>=1&&nums[i]==nums[i-1])
直接跳过寻找下一个i,因为当a等于nums[i-1]的时
候,nums[i-1]为首的相加的三个数字为零的情况,
已近全部被找到;

3.3 如果此时nums[i]+nums[l]+nums[r]>targetr r--,
如果num[i]+nums[l]+nums[r]<target,l++,
如果nums[i]+nums[l]+nums[r]==target,就要判
断是否这个答案存在过

3.4 一开始我是这么判断的,但会超时,最后两个点
过不掉,因此我们要进行优化;
			List<Integer>res=new ArrayList<Integer>();
                 res.add(nums[i]);
                 res.add(nums[l]);
                 res.add(nums[r]);
                 if(!ans.contains(res))
                 ans.add(res);
                 
3.5 这里的优化跟3.2所讲的意思差不多,如果
nums[l]==nums[l+1],l++,在a和b都确定的情
况下c一定是确定的,既然c是确定的那么对c也要
做相同的判断,去重c


代码:

class Solution {
    
    
    public List<List<Integer>> threeSum(int[] nums) {
    
    
    List<List<Integer>> ans=new ArrayList();
    if(nums.length==0||nums.length<3)
    return  new ArrayList();
    Arrays.sort(nums);
    int end=nums.length-1;
     for(int i=0;i<nums.length-2;i++){
    
    
         if(nums[i]>0)
         break;
         if(i>=1&&nums[i]==nums[i-1])
         continue;
         
         int l=i+1;
         int r=end;
         while(l<r){
    
    
             if(nums[i]+nums[l]+nums[r]>0)
             r--;
             else if(nums[i]+nums[l]+nums[r]<0)
             l++;
             else if(nums[i]+nums[l]+nums[r]==0){
    
    

                //  List<Integer>res=new ArrayList<Integer>();
                //  res.add(nums[i]);
                //  res.add(nums[l]);
                //  res.add(nums[r]);
                  ans.add(Arrays.asList(nums[i], nums[l], nums[r]));
                  while (l<r && nums[l] == nums[l+1]) l++; // 去重
                  while (l<r && nums[r] == nums[r-1]) r--;           
                  r--;
                  l++;
             }
         }
     }
     return ans;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_44844588/article/details/108145891