16. 最接近的三数之和(javascript)16. 3Sum Closest
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
解题参考:画解算法:15. 三数之和
刚开始尝试中等的题目,没办法自己太菜了,想不出来,只能参考前辈们的解题思路,这个是我觉得最好理解的了(反正我是这么认为的,O(∩_∩)O哈哈~)
废话不多说,开始
根据题意, 会发现一个特殊的,当!nums为真或者长度小于3,都会返回一个空数组
解题思路:
- 将数组进行升序排列,再进行遍历,当发现第一项都大于0,肯定不存在,退出循环
- i > 0 && nums[i] == nums[i - 1]会导致结果重复,跳过
- 两个指针:一个指向i+1,一个指向len-1,进行初始化,l++,r–,往中间靠拢,相遇时循环结束,这是内部循环
- sum = nums[i] + nums[l] + nums[r];
sum和0比较:
大于0,说明nums[r]大了,往左移一位;
小于0,说明nums[l]小了,往右移一位;
等于0,说明符合条件,将数组push到res 里面,两个指针忘中间移动
当 sum == 0 时,nums[l] == nums[l+1] 则会导致结果重复,应该跳过,l++
当 sum == 0 时,nums[r] == nums[r-1] 则会导致结果重复,应该跳过,r−−
var threeSum = function (nums) {
let res = []
let len = nums.length
if (!nums || len < 3) return res
nums.sort((a, b) => { return a - b })//进行升序排列
for (let i = 0; i < len; i++) {
if (nums[i] > 0) break//第一项都大于0,不存在等于0
if (i > 0 && nums[i] == nums[i - 1]) continue;//会导致结果重复,跳过
let l = i + 1;
let r = len - 1;
while (l < r) {
const sum = nums[i] + nums[l] + nums[r]
if (sum == 0) {
res.push([nums[i], nums[l], nums[r]])
while (l < r && nums[l] == nums[l + 1]) l++//会导致结果重复,跳过
while (l < r && nums[r] == nums[r - 1]) r--//会导致结果重复,跳过
l++
r--
} else if (sum < 0) {
l++
} else if (sum > 0) {
r--
}
}
}
return res
};
leetcode:https://leetcode.cn/problems/3sum/
可参考官方解题:
https://leetcode.cn/problems/3sum/solution/san-shu-zhi-he-by-leetcode-solution/