LeetCode 18 - 4Sum

Given an array S of n integers, are there elements abc, 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)

Solution 1:

public List<List<Integer>> fourSum(int[] num, int target) {
    List<List<Integer>> result = new ArrayList<>();
    int len = num.length;
    if(len < 4) return result;
    Arrays.sort(num);
    for(int i=0; i<len-3; i++) {
        if(i>0 && num[i]==num[i-1]) continue;
        for(int j=i+1; j<len-2; j++) {
            if(j>i+1 && num[j]==num[j-1]) continue;
            int start = j+1;
            int end = len-1;
            while(start < end) {
                int sum = num[i]+num[j]+num[start]+num[end];
                if(sum == target) {
                    List<Integer> quadruplet = new ArrayList<>();
                    quadruplet.add(num[i]);
                    quadruplet.add(num[j]);
                    quadruplet.add(num[start]);
                    quadruplet.add(num[end]);
                    result.add(quadruplet);
                    do {
                        start++;
                    }while(start < end && num[start] == num[start-1]);
                    do {
                        end--;
                    }while(start < end && num[end] == num[end+1]);
                } else if(sum < target) {
                    start++;
                } else {
                    end--;
                }
            }
        }
    }
    return result;
}

 

Solution 2:

public List<List<Integer>> fourSum(int[] num, int target) {
    // Since we use set here, we don't need to dedup data
    Set<List<Integer>> result = new HashSet<>();
    Arrays.sort(num);
    Map<Integer, Set<Pair>> map = new HashMap<>();
    
    for (int i=0; i<num.length; i++) {
        for (int j=0; j<i-1; j++) {
            int a = num[j], b = num[i-1];
            if (!map.containsKey(a+b)) {
                map.put(a+b, new HashSet());
            }
            map.get(a+b).add(new Pair(a, b));
        }
        // Note the order of these two for-loops is critical
        for (int j=i+1; j<num.length; j++) {
            int pairSum = target - num[i] - num[j];
            if (map.containsKey(pairSum)) {
                for (Pair p : map.get(pairSum)) {
                    List l = new LinkedList();
                    l.add(p.first);
                    l.add(p.second);
                    l.add(num[i]);
                    l.add(num[j]);
                    result.add(l);
                }
            }
        }
    }
    return new ArrayList<List<Integer>>(result);
}
class Pair {
    int first;
    int second;
    public Pair(int first, int second) {
        this.first = first;
        this.second = second;
    }
    @Override
    public int hashCode() {
        return first*31 + second;
    }
    @Override
    public boolean equals(Object d){ 
        if (d == this) return true;
        if (!(d instanceof Pair)) return false;
        Pair p = (Pair) d;
        return (this.first == p.first) && (this.second == p.second);
    }
}

 

Reference:

http://lifexplorer.me/leetcode-3sum-4sum-and-k-sum/

猜你喜欢

转载自yuanhsh.iteye.com/blog/2208736