一、题目内容 中等
给你一个由 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 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
二、解题思路
跟三数之和,差不多思路。由于是 a + b + c + d = target,很自然的思路,多加一层 for 循环。
在这个过程中,需要注意的就是,重复值。我们举个例子**[-2,-2,-2,-1,-1,1,1,2,2]**
,target = 0
- 首先,a = nums[0],b = nums[1],left = nums[2],right = nums[3]
a + b + left + right > target
,说明 right 太大,需要减小a + b + left + right < target
,说明 left 太小,需要增加- 相等则美滋滋
当我们 b 从 nums[1] 变成 nums[2] 时,由于两个数都是相等的,所以跳过
- 单纯写成
nums[j] === nums[j -1]
可以吗? - 不可以,你想想 b = nums[1] 的时候,nums[0] 也是 -2,但是 nums[0] 是赋给 a 的
- 所以我们要再加一个条件
j !== i + 1 && nums[j] === nums[j -1]
,说明数属于 b三、具体代码
```javascript /**
- @param {number[]} nums
- @param {number} target
@return {number[][]} */ var fourSum = function (nums, target) { nums.sort((a, b) => a - b) const result = [] for (let i = 0, len = nums.length; i < len; i++) { if (nums[i] === nums[i - 1]) continue
for (let j = i + 1; j < len; j++) { let left = j + 1, right = len - 1; const curTarget = target - (nums[i] + nums[j]) if (j !== i + 1 && nums[j] === nums[j - 1]) continue
while (left < right) { if (nums[left] + nums[right] > curTarget) {
while (left < right && nums[right] === nums[right - 1]) right -= 1
right -= 1
} else if (nums[left] + nums[right] < curTarget) {
while (left < right && nums[left] === nums[left + 1]) left += 1
left += 1
} else {
result.push([nums[i], nums[j], nums[left], nums[right]])
while (left < right && nums[left] === nums[left + 1]) left += 1
while (left < right && nums[right] === nums[right - 1]) right -= 1
right -= 1
left += 1
四、其他解法
- 单纯写成