题目
Given an array S of n integers, are there elements a,b,c, andd 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)
思路
如果会做3Sum那道题的话,这道题也就非常简单了,只不过这道题比3Sum多了一层循环嵌套而已,算法的时间复杂度为O(n^3)。总之这类kSum问题,都有类似的解法,甚至可以用递归做,最优解法的时间复杂度为O(n^(k-1)),网上有严格的数学证明。
代码
Python
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
leng = len(nums)
res = []
if (nums == None or leng < 4):
return res
nums.sort()
for i in xrange(0,leng-1):
#外层去重
if (i > 0 and nums[i] == nums[i-1]):
continue
for j in xrange(i+1,leng):
#内层去重
if (j > i+1 and nums[j] == nums[j-1]):
continue
p = j + 1
q = leng - 1
while (p < q):
#固定nums[i]和nums[j],从首尾往中间靠拢找结果
fsum = nums[i] + nums[j] + nums[p] + nums[q]
if (fsum < target):
p += 1
elif (fsum > target):
q -= 1
else:
item = []
item.append(nums[i])
item.append(nums[j])
item.append(nums[p])
item.append(nums[q])
res.append(item)
while (True):
p += 1
if (p < q and nums[p] == nums[p-1]):
continue
else:
break
while (True):
q -= 1
if (q > p and nums[q] == nums[q+1]):
continue
else:
break
return res
Java
public class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if (nums == null || nums.length < 4) return res;
//先对数组排序
Arrays.sort(nums);
int len = nums.length;
int i,j,p,q,sum;
for (i = 0;i < len-1;i++){
//外层去重
if (i > 0 && nums[i] == nums[i-1]) continue;
for (j = i+1;j < len;j++){
//内层去重
if (j > i+1 && nums[j] == nums[j-1]) continue;
p = j + 1;
q = len - 1;
while (p < q){
//固定nums[i]和nums[j],从头尾两端找符合target的数
sum = nums[i] + nums[j] + nums[p] + nums[q];
if (sum < target) p++;
else if (sum > target) q--;
else{
List<Integer> item = new ArrayList<Integer>();
item.add(nums[i]);
item.add(nums[j]);
item.add(nums[p]);
item.add(nums[q]);
res.add(item);
while ( (p+=1)<q && nums[p-1] == nums[p]);
while ( (q-=1)>p && nums[q+1] == nums[q]);
}
}
}
}
return res;
}
}