本题和四数之和很像,但是四数之和是使用哈希表来做,转换成两数之和的思路来实现的。两层for循环就可以确定 a 和b 的数值了,可以使用哈希法来确定 0-(a+b) 是否在 数组里出现过,其实这个思路是正确的,但是我们有一个非常棘手的问题,就是题目中说的不可以包含重复的三元组。本题采用双指针加上排序来实现。
import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
        //存放最终答案的二维数组
        ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
        int len = num.length;
        if(len<3)return ans;
        Arrays.sort(num);
 
        for(int i=0;i<len;i++){
          //如果nums[i]已经大于0,就没必要继续往后了,因为和就是0啊
            if(num[i]>0) return ans;
            //注意考虑越界i>0,主要功能是排除重复值
            if(i>0 && num[i]==num[i-1]){
                continue;
            }
            //声明指针
            int cur = num[i];
            int left = i+1;
              //从尾部开始
            int right =len-1;
            while(left<right){
              //如果已经找到和为0
               if(cur+num[left]+num[right]==0){
                  //创建一个数组,并将满足条件的三元素放进去
                   ArrayList<Integer> list = new ArrayList<>();
                   list.add(cur);
                   list.add(num[left]);
                   list.add(num[right]);
                   ans.add(list);
                    // 去重逻辑应该放在找到一个三元组之后
                   //判断是left指针指向是否重复
                  while(left<right && num[left]==num[left+1]) left++;
                  //判断是right指针指向是否重复
                  while(left<right && num[right]==num[right-1])right--;
                  //移动指针
                   left++;
                   right--;
               }else if(cur+num[left]+num[right]<0){
                   left++;
               }else{
                   right--;
               }
            }
        }
        return ans;
    }
}