前言
数据结构与算法属于开发人员的内功,不管前端技术怎么变,框架怎么更新,版本怎么迭代,它终究是不变的内容。 始终记得在参加字节青训营的时候,月影老师说过的一句话,不要问前端学不学算法。计算机学科的每一位都有必要了解算法,有
写出高质量代码的潜意识
。
一、问题描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4] 输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = [] 输出:[]
示例 3:
输入:nums = [0] 输出:[]
二、思路讲解
这里借用代码随心录大佬的动图
迭代 + 双指针
排序为什么要排序? 可以节省掉一部分的case,例如当最外层的迭代已经大于0
双指针
- 左指针指向当前外层迭代的元素的下一个元素,右指针指向最后一个元素。
- 从左往右依次从小到大,所以当三数之和大于0的时候右指针左移,小于的时候左指针右移。
- 当满足三数之和为0的时候,左右指针都需要移动,避免找到重复的值。 (这里为什么需要左右指针都改变的原因是:无论是n2还是n3的值发生改变另一个都要发生改变)
三、AC代码
var threeSum = function(nums) { nums.sort((a, b)=> a - b) const res = [] for(let i = 0; i < nums.length - 2; i++){ // 外层迭代 let n1 = nums[i] if(n1>0) break // nums是递增的所以当n1的值大于0的时候可以直接返回 if(i >= 1 && n1 == nums[i - 1]) continue let left = i + 1 , right = nums.length - 1 // 左指针和右指针 while(left < right){ let n2 = nums[left] , n3 = nums[right] if(n1 + n2 + n3 === 0){ res.push([n1, n2, n3]) while(left < right && n2 == nums[left]) left++ // 找到和n2不同的左值 while(left < right && n3 == nums[right]) right-- }else if(n1 + n2 + n3 < 0){ left++ }else{ right-- } } } return res };
后续
- 地址: 三数之和
好了,本篇 力扣-三数之和
到这里就结束了,我是邵小白,一个在前端领域摸爬滚打的大三学生,欢迎👍评论。