classSolution {public List> fourSum(int[] nums, inttarget) {
List> ret = new ArrayList<>();
Map>> twoSum = new HashMap<>();
Map cnt = new HashMap<>(); //count of each num//sort array
Arrays.sort(nums);for(int i = 0; i < nums.length; i++){//update count
if(cnt.get(nums[i])==null)
cnt.put(nums[i],1);elsecnt.put(nums[i],cnt.get(nums[i])+1);//initialize map
if(i>0 && nums[i]==nums[i-1]) continue;//avoid repeat
for(int j = i+1; j < nums.length; j++){if(j > i+1 && nums[j]==nums[j-1]) continue; //avoid repeat
List list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
List> listGroup = twoSum.get(nums[i]+nums[j]);if(listGroup ==null){
listGroup= new ArrayList<>();
}
listGroup.add(list);
twoSum.put(nums[i]+nums[j], listGroup);
}
}//iterate map to find target sum
Set keys =twoSum.keySet();for (intkey : keys) {
List> listGroupA =twoSum.get(key);for(ListlistA: listGroupA){
List> listGroupB = twoSum.get(target -key);if(listGroupB == null) continue;for(ListlistB: listGroupB){//check whether count of num is enough
int a = listA.get(0);int b = listA.get(1);int c = listB.get(0);int d = listB.get(1);if(Math.max(a,b) > Math.min(c,d)) continue; //四个数两两组合,有6种情况,这里只取两个最小的数在listA的情况,去重//check count of num
cnt.put(a,cnt.get(a)-1);
cnt.put(b,cnt.get(b)-1);
cnt.put(c,cnt.get(c)-1);
cnt.put(d,cnt.get(d)-1);if(cnt.get(a) >= 0 && cnt.get(b) >= 0 && cnt.get(c) >= 0 && cnt.get(d) >= 0){//find one list
List listC = new ArrayList<>();
listC.addAll(listA);
listC.addAll(listB);
ret.add(listC);
}//recover count of num
cnt.put(a,cnt.get(a)+1);
cnt.put(b,cnt.get(b)+1);
cnt.put(c,cnt.get(c)+1);
cnt.put(d,cnt.get(d)+1);
}
}
}returnret;
}
}