import java.util.*; 
public class Solution {
     public  ArrayList<ArrayList<Integer>> threeSum(int[] num) {

        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        Arrays.sort(num);
        int prev = Integer.MIN_VALUE;
        for (int i = 0; i < num.length; ) {
            int start = i;
            while (num[start] == prev) {
                start++;
                if (start >= num.length) {
                    return res;
                }
            }

            prev = num[start];

            List<Integer> sec = twoSum(num, -num[start], start+1, num.length - 1);
            if (sec != null) {
                for (int j = 0; j < (sec.size()/2); j++) {
                    ArrayList<Integer> temp = new ArrayList<>();
                    temp.add(num[start]);
                    temp.add(sec.get(2*j+0));
                    temp.add(sec.get(2*j+1));
                    res.add(temp);
                }

            }
            i = start++;
        }

        return res;
    }


     List<Integer> twoSum(int[] num, int target, int low, int high) {
        int sum;
        List<Integer> ret=new ArrayList<>();
        while (low < high) {
            int left=num[low];
            int right=num[high];
            sum = num[low] + num[high];
            if (sum > target) {
                while(num[high]==right  && low < high){
                    high--;
                }
            } else if (sum < target) {
                while(num[low]==left  && low < high){
                    low++;
                }
            } else {
                ret.add(num[low]);
                ret.add(num[high]);
                while(num[high]==right  && low < high){
                    high--;
                }
                while(num[low]==left  && low < high){
                    low++;
                }
            }
        }
        //cant find
        return ret;
    }
}