leetcode

Four Sum

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d) The solution set must not contain duplicate quadruplets.

   For example, given array S = {1 0 -1 0 -2 2}, and target = 0.
   A solution set is:
    (-1,  0, 0, 1)
    (-2, -1, 1, 2)
    (-2,  0, 0, 2)

O(n3), add an additional inner loop to perform three sum logic.

public List<List<Integer>> fourSum(int[] num, int target) {
        List<List<Integer>> results = new ArrayList<List<Integer>>();
        if (num==null||num.length<4) {
            return results;
        }

        Arrays.sort(num);

        for (int i=0; i<num.length-3; i++) {
            if (i==0 || num[i]>num[i-1]) {
                for (int j=i+1; j<num.length-2; j++) {
                    if (j==i+1 || num[j]>num[j-1]) {
                        int reverseTarget = target - num[i] - num[j];
                        int start = j+1;
                        int end = num.length-1;
                        while (start<end) {
                            if (num[start] + num[end] == reverseTarget) {
                                List<Integer> result = new ArrayList<Integer>();
                                result.add(num[i]);
                                result.add(num[j]);
                                result.add(num[start]);
                                result.add(num[end]);
                                start = start + 1;
                                end = end - 1;
                                results.add(result);

                                //compare current start and previous start, if same keep going
                                while (start<end&&num[start]==num[start-1]) {
                                    start = start + 1;
                                }
                                while (start<end&&num[end]==num[end+1]) {
                                    end = end - 1;
                                }
                            } else if (num[start] + num[end] < reverseTarget) {
                                start = start + 1;
                            } else {
                                end = end - 1;
                            }           
                        }
                    }                       
                }                       
            }
        }
        return results;
    }