思路
本题做法与上一篇三数相加的做法相似,同样是使用双指针法,区别是这里多嵌一层循坏,遍历 i 和 j 的值( j = i + 1),思路可参考笔记:
【JS】双指针法获得满足三数之和且不重复的三元组https://blog.csdn.net/m0_74662483/article/details/143094640?spm=1001.2014.3001.5501
步骤
检查数组长度:首先检查输入数组
nums
的长度是否小于4,如果是,则直接返回空数组,因为无法形成四元组。排序数组:对数组
nums
进行升序排序,这样可以帮助我们在后面使用双指针法时避免重复的组合。遍历数组:使用三层嵌套循环来遍历数组,寻找可能的四元组组合。
- 第一层循环变量
i
从0开始,到len - 3
结束,因为每个四元组需要4个不同的数字。- 第二层循环变量
j
从i + 1
开始,到len - 2
结束。跳过重复元素:在第一层和第二层循环中,如果当前元素与前一个元素相同,则跳过当前迭代,以避免生成重复的四元组。
初始化左右指针:对于每一对
(i, j)
,初始化两个指针left
和right
,分别指向j + 1
和len - 1
。双指针法:使用
while
循环,通过移动left
和right
指针来寻找和为target
的四元组。
- 如果当前四元素之和小于
target
,则移动left
指针到下一个元素。- 如果当前四元素之和大于
target
,则移动right
指针到前一个元素。- 如果当前四元素之和等于
target
,则找到了一个有效的四元组,将其添加到结果数组res
中。去重:在找到有效的四元组后,通过两个
while
循环跳过所有重复的元素,以避免在后续的迭代中生成重复的四元组。移动指针:在每次找到有效的四元组后,移动
left
和right
指针以继续寻找下一个可能的四元组。返回结果:遍历结束后,返回包含所有不重复四元组的结果数组
res
。
题目
示例代码
var fourSum = function (nums, target) {
const len = nums.length; // 获取数组长度
if (len < 4) return []; // 如果数组长度小于4,直接返回空数组,因为无法形成四元组
// 对数组进行排序,以便后续使用双指针法
nums.sort((a, b) => a - b);
const res = []; // 初始化结果数组
// 外层循环,遍历数组的每个元素作为四元组的第一个数
for (let i = 0; i < len - 3; i++) {
// 跳过重复元素,以避免生成重复的四元组
if (i > 0 && nums[i] === nums[i - 1]) continue;
// 第二个循环,从第一个元素的下一个位置开始,遍历作为四元组的第二个数
for (let j = i + 1; j < len - 2; j++) {
// 跳过重复元素
if (j > i + 1 && nums[j] === nums[j - 1]) continue;
// 初始化左右指针
let left = j + 1, right = len - 1;
// 内层循环,使用双指针法寻找和为 target 的四元组
while (left < right) {
let sum = nums[i] + nums[j] + nums[left] + nums[right]; // 计算当前四元组的和
// 如果和小于 target,移动左指针以增大和
if (sum < target) {
left++;
} else if (sum > target) { // 如果和大于 target,移动右指针以减小和
right--;
} else {
// 如果和等于 target,找到一个有效的四元组
res.push([nums[i], nums[j], nums[left], nums[right]]);
// 跳过所有重复的左指针元素
while (left < right && nums[left] === nums[left + 1]) left++;
// 跳过所有重复的右指针元素
while (left < right && nums[right] === nums[right - 1]) right--;
// 移动指针寻找下一个可能的四元组
left++;
right--;
}
}
}
}
// 返回包含所有有效四元组的结果数组
return res;
};
欢迎指正!