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)
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/