双指针的思想,先将数组排序,之后设定当前值(遍历即可),然后在当前值后一位为left指针,数组尾为right指针,将当前值和指针指向的数字相加判断大小,等于0则记录,小于零移动left,大于0移动right。同时注意重复值的过滤,若果重复讲指针移动,以及当前值重复的话跳出本次循环,移动后再进入循环。

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    
        if(num.length < 3){
            return res;
        }
       Arrays.sort(num);
       for(int i = 0;i<num.length;i++){
           int cur = num[i];
           int left = i+1;
           int right = num.length-1;
           //最小值大于0了,没有相加的必要了。
             if(cur>0){
                   return res;
               }
              if(i>0 && num[i]==num[i-1]){
                continue;
              }
           while(left<right){
               if(cur + num[left] + num[right] == 0){
                   ArrayList<Integer> arr = new ArrayList<>();
                   arr.add(cur);
                   arr.add(num[left]);
                   arr.add(num[right]);
                   res.add(arr);
                   while(left<right&&num[left] == num[left+1]){
                        left = left + 1;
                    }
                    while(left<right&&num[right] == num[right-1]){
                        right = right - 1;
                    }
                    left++;
                    right--;
               }else if(cur + num[left] + num[right]<0){
                   left = left + 1;
               }else{
                   right =right - 1;
               }
           }
               
           }
           return res;
       }

    }