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: 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] ]思路:用Two Sum的思想,用hashmap去找pair的sum,这样做可以做到O(N^2)的。注意去重复。
public class Solution {
class Pair {
private int i;
private int j;
Pair(int i, int j){
this.i = i;
this.j = j;
}
}
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> lists = new ArrayList<List<Integer>>();
if(nums == null || nums.length < 4) return lists;
HashMap<Integer, List<Pair>> hashmap = new HashMap<Integer, List<Pair>>();
for(int i=0; i<nums.length-1; i++){
for(int j=i+1; j<nums.length; j++){
int sum = nums[i]+nums[j];
if(hashmap.containsKey(sum)){
hashmap.get(sum).add(new Pair(i, j));
} else {
List<Pair> list = new ArrayList<Pair>();
list.add(new Pair(i, j));
hashmap.put(sum,list);
}
}
}
HashSet<List<Integer>> hashset = new HashSet<List<Integer>>();
Iterator its = hashmap.entrySet().iterator();
while(its.hasNext()){
Map.Entry pairs = (Map.Entry)its.next();
int a = (Integer)pairs.getKey();
List<Pair> list1 = (List<Pair>)pairs.getValue();
List<Pair> list2 = (List<Pair>)hashmap.get(target-a);
if(list2 != null){
for(Pair p1: list1){
for(Pair p2: list2){
if( (p1.i == p2.i)
|| (p1.i == p2.j)
|| (p1.j == p2.i)
|| (p1.j == p2.j)){
continue;
} else {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(nums[p1.i]);
list.add(nums[p1.j]);
list.add(nums[p2.i]);
list.add(nums[p2.j]);
Collections.sort(list);
if(!hashset.contains(list)){
hashset.add(list);
lists.add(list);
}
}
}
}
}
}
return lists;
}
}
思路2: O(N^3)的方法,用hashset去重复。
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> lists = new ArrayList<List<Integer>>();
if(nums == null || nums.length == 0) return lists;
Arrays.sort(nums);
HashSet<List<Integer>> hashset = new HashSet<List<Integer>>();
for(int i=0; i<nums.length-3; i++){
for(int j=i+1; j<nums.length-2; j++){
int k = j+1; int l = nums.length-1;
while(k<l){
int sum = nums[i]+nums[j]+nums[k]+nums[l];
if(sum < target){
k++;
} else if(sum > target){
l--;
} else { // sum == 0;
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
list.add(nums[l]);
if(!hashset.contains(list)){
hashset.add(list);
lists.add(list);
}
k++;
l--;
}
}
}
}
return lists;
}
}
思路3:O(n^3)的方法,用指针去重复。注意第二层循环去重是: j>i+1 && nums[j] == nums[j-1]
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> lists = new ArrayList<List<Integer>>();
if(nums == null || nums.length == 0) return lists;
Arrays.sort(nums);
for(int i=0; i<nums.length-3; i++){
if(i>0 && nums[i] == nums[i-1]){
continue;
}
for(int j=i+1; j<nums.length-2; j++){
if(j>i+1 && nums[j] == nums[j-1]){ // 注意这里是j>i+1
continue;
}
int k = j+1; int l = nums.length-1;
while(k<l){
int sum = nums[i] + nums[j] + nums[k] + nums[l];
if(sum == target){ // 注意是target,不是0;
List<Integer> list = new ArrayList<Integer>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[k]);
list.add(nums[l]);
lists.add(list);
k++;
l--;
while(k<l && nums[k] == nums[k-1] && nums[l] == nums[l+1]){
k++;
l--;
}
} else if( sum < target){
k++;
} else {
l--;
}
}
}
}
return lists;
}
}