题目来源:https://leetcode.com/problems/4sum/
问题描述
18. 4Sum
Medium
Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums 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.
Example:
Given array nums = [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]
]
------------------------------------------------------------
题意
给出一个整数序列和一个整数target,求序列中的所有这样的四个数,使得四数之和等于target.
------------------------------------------------------------
思路
用HashMap存储序列中所有二元数对的和[O(n^2)],key为数对和,value为二元组的HashSet,遍历HashMap找到两个数对,其和为target[O(n^2)]。如果二元组的和分布均匀的话,总的复杂度近似为O(n^2).
具体实现上,要注意用HashSet去掉重复的元组。
------------------------------------------------------------
代码
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
int i = 0, j = 0, sum = 0, n = nums.length;
if (n < 4)
{
return Collections.emptyList();
}
HashMap<Integer, HashSet<HashSet<Integer>>> twoSum = new HashMap<Integer, HashSet<HashSet<Integer>>>();
Set<ArrayList<Integer>> retSet = new HashSet<>();
Set<List<Integer>> ret = new HashSet<>();
for (i=0; i<n-1; i++)
{
for (j=i+1; j<n; j++)
{
HashSet<Integer> twoInd = new HashSet<Integer>();
twoInd.add(i);
twoInd.add(j);
sum = nums[i] + nums[j];
if (twoSum.get(sum) == null)
{
twoSum.put(sum, new HashSet<>());
}
twoSum.get(sum).add(twoInd);
}
}
Iterator iter = twoSum.entrySet().iterator();
while (iter.hasNext())
{
HashMap.Entry entry = (HashMap.Entry) iter.next();
Integer key = (Integer)entry.getKey();
HashSet<HashSet<Integer>> val1 = (HashSet<HashSet<Integer>>)entry.getValue();
HashSet<HashSet<Integer>> val2 = twoSum.get(target - key);
if (val2 == null)
{
continue;
}
Iterator it1 = val1.iterator();
while (it1.hasNext())
{
HashSet<Integer> set1 = (HashSet<Integer>) it1.next();
Iterator it2 = val2.iterator();
while (it2.hasNext())
{
HashSet<Integer> set2 = (HashSet<Integer>) it2.next();
HashSet<Integer> Inds = new HashSet<Integer>(set1);
Inds.addAll(set2);
if (Inds.size() == 4)
{
ArrayList<Integer> arr = new ArrayList<Integer>();
Iterator _iter = Inds.iterator();
while (_iter.hasNext())
{
arr.add(nums[(Integer) _iter.next()]);
}
Collections.sort(arr);
retSet.add(arr);
}
}
}
}
return new LinkedList(retSet);
}
}