题目描述
给定一个包含 n 个整数的数组 nums
和一个目标值 target
,判断 nums
中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target
相等?找出所有满足条件且不重复的四元组。
注意:
答案中不可以包含重复的四元组。
示例:
给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
题解
KSum
参考论坛大神的 Java KSum 方法。
思路是所有的 k sum 问题可以划分为两个问题:
2 sum 问题
将 k sum 问题变为 k -1 sum 问题
使用递归来解决该问题,时间复杂度为 O(N^(K-1))。
public class Solution
{
private int _len;
public IList<IList<int>> FourSum(int[] nums, int target) {
_len = nums.Length;
nums = nums.OrderBy(n => n).ToArray();
return KSum(nums, target, 4, 0);
}
private IList<IList<int>> KSum(int[] nums, int target, int k, int index)
{
var res = new List<IList<int>>();
if (index >= _len) return res;
if (k == 2)
{
int i = index, j = _len - 1;
while (i < j)
{
// Find a pair
if (target - nums[i] == nums[j])
{
res.Add(new List<int> { nums[i], target - nums[i] });
// Skip duplication
while (i < j && nums[i] == nums[i + 1]) i++;
while (i < j && nums[j - 1] == nums[j]) j--;
i++;
j--;
}
// Move left bound
else if (target - nums[i] > nums[j]) i++;
// Move right bound
else j--;
}
}
else
{
for (var i = index; i < _len - k + 1; i++)
{
// Use current number to reduce K Sum into K-1 Sum
var temp = KSum(nums, target - nums[i], k - 1, i + 1);
if (temp.Any())
{
// Add previous results
foreach (var t in temp)
{
t.Add(nums[i]);
}
res.AddRange(temp);
}
// Skip duplicated numbers
while (i < _len - 1 && nums[i] == nums[i + 1]) i++;
}
}
return res;
}
}