这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
11. 四数之和 (4sum)
标签
- 排序
- 双指针
- 中等
题目
这里不贴题了,leetcode打开就行,题目大意:
给定一个数组,要求在这个数组中找出 4 个数之和为 0 的所有组合。本题的难点在于如何去除重复解。跟三数只和基本一样思路。
基本思路
跟三数之和基本一模一样,唯一不一样的是三数中间定了一个 i,4数需要两个 for 来定两位组合。
写法实现
/**
* @param {number[]} nums
* @param {number} target
* @return {number[][]}
*/
var fourSum = function(nums, target) {
let [res, len, first, second, left, right, sum] = [[], nums.length, 0, 0, 0, 0, 0]
// 特判
if (len < 4) {
return []
}
// 先排序
nums = nums.sort((a, b) => a - b)
// 前面两个指针,第一个从 0 ~len-3(第一个指针,后面数不够了至少要4个)
// 第二个是跟在第一个之后 所以是 first + 1
for (first = 0; first < len - 3; first++) {
if (first > 0 && nums[first] === nums[first-1]) {
continue
}
for(second = first + 1; second < len - 2; second++) {
if (second > first+1 && nums[second] === nums[second-1]) {
continue;
}
// 临时变量记录前两个选定数的和
let tempSum = nums[first] + nums[second]
// 再用双指针来处理
left = second + 1
right = len - 1
while (left < right) {
sum = tempSum + nums[left] + nums[right]
// 和等于 0 满足条件 进结果数组
if (sum === target) {
res.push([nums[first], nums[second], nums[left], nums[right]])
// 判断左界和右界是否和下一位置重复,去除重复解。
while (left < right && nums[left] === nums[left+1]) {
left++
}
while (left < right && nums[right] === nums[right-1]) {
right--
}
// 并同时将 left,right 移到下一位置,寻找新的解
left++
right--
} else if (sum > target) {
// 和大于 0 的情况,说明 nums[right] 太大,right 左移
right--
} else {
left++
}
}
}
}
return res
};
let nums = [-2,-1,-1,1,1,2,2], target = 0
console.log(fourSum(nums, target))
年初一就来一题吧。
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦
搜索我的微信号infinity_9368,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我
presious tower shock the reiver monster,我看到就通过,暗号对不上不加哈