给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

    0 <= a, b, c, d < n
    a、b、c 和 d 互不相同
    nums[a] + nums[b] + nums[c] + nums[d] == target
    你可以按 任意顺序 返回答案 。

    示例 1:

    输入:nums = [1,0,-1,0,-2,2], target = 0
    输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
    示例 2:

    输入:nums = [2,2,2,2,2], target = 8
    输出:[[2,2,2,2]]

    1. /**
    2. * @param {number[]} nums
    3. * @param {number} target
    4. * @return {number[][]}
    5. */
    6. var fourSum = function (nums, target) {
    7. // 简化成2数之和,双指针解法
    8. // 先排序
    9. nums.sort((a, b) => a - b);
    10. const nSum = (nums, n, start, target) => {
    11. let res = [];
    12. let length = nums.length;
    13. // 小于二没意义,当然这里不需要加
    14. if (n < 2 || length < n) return res;
    15. // 初始化 基础两数之和
    16. if (n === 2) {
    17. let l = start, r = length - 1;
    18. while (l < r) {
    19. // 储存第一次出现值
    20. let left = nums[l], right = nums[r];
    21. let sum = left + right;
    22. if (sum < target) {
    23. while (l < r && left === nums[l]) l++;
    24. } else if (sum > target) {
    25. while (l < r && right === nums[r]) r--;
    26. } else {
    27. res.push([left, right]);
    28. while (l < r && left === nums[l]) l++;
    29. while (l < r && right === nums[r]) r--;
    30. }
    31. }
    32. } else {
    33. // 处理多数时
    34. for (let i = start; i < length; i += 1) {
    35. // 这里递归赋值转两数之和
    36. let sub = nSum(nums, n - 1, i + 1, target - nums[i]);
    37. // 取返回res
    38. for (let arr of sub) {
    39. // 合并进res
    40. res.push([...arr, nums[i]])
    41. }
    42. // 跳过重复
    43. while (i < length - 1 && nums[i] === nums[i + 1]) i += 1
    44. }
    45. }
    46. return res;
    47. }
    48. return nSum(nums, 4, 0, target)
    49. };

    image.png