题目描述

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,cd ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:
答案中不可以包含重复的四元组。

示例:

  1. 给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0
  2. 满足要求的四元组集合为:
  3. [
  4. [-1, 0, 0, 1],
  5. [-2, -1, 1, 2],
  6. [-2, 0, 0, 2]
  7. ]

题解

KSum

参考论坛大神的 Java KSum 方法。

思路是所有的 k sum 问题可以划分为两个问题:

  1. 2 sum 问题

  2. 将 k sum 问题变为 k -1 sum 问题

使用递归来解决该问题,时间复杂度为 O(N^(K-1))。

  1. public class Solution
  2. {
  3. private int _len;
  4. public IList<IList<int>> FourSum(int[] nums, int target) {
  5. _len = nums.Length;
  6. nums = nums.OrderBy(n => n).ToArray();
  7. return KSum(nums, target, 4, 0);
  8. }
  9. private IList<IList<int>> KSum(int[] nums, int target, int k, int index)
  10. {
  11. var res = new List<IList<int>>();
  12. if (index >= _len) return res;
  13. if (k == 2)
  14. {
  15. int i = index, j = _len - 1;
  16. while (i < j)
  17. {
  18. // Find a pair
  19. if (target - nums[i] == nums[j])
  20. {
  21. res.Add(new List<int> { nums[i], target - nums[i] });
  22. // Skip duplication
  23. while (i < j && nums[i] == nums[i + 1]) i++;
  24. while (i < j && nums[j - 1] == nums[j]) j--;
  25. i++;
  26. j--;
  27. }
  28. // Move left bound
  29. else if (target - nums[i] > nums[j]) i++;
  30. // Move right bound
  31. else j--;
  32. }
  33. }
  34. else
  35. {
  36. for (var i = index; i < _len - k + 1; i++)
  37. {
  38. // Use current number to reduce K Sum into K-1 Sum
  39. var temp = KSum(nums, target - nums[i], k - 1, i + 1);
  40. if (temp.Any())
  41. {
  42. // Add previous results
  43. foreach (var t in temp)
  44. {
  45. t.Add(nums[i]);
  46. }
  47. res.AddRange(temp);
  48. }
  49. // Skip duplicated numbers
  50. while (i < _len - 1 && nums[i] == nums[i + 1]) i++;
  51. }
  52. }
  53. return res;
  54. }
  55. }