力扣-三数之和 中等 🐱‍🐉

155 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

前言

数据结构与算法属于开发人员的内功,不管前端技术怎么变,框架怎么更新,版本怎么迭代,它终究是不变的内容。 始终记得在参加字节青训营的时候,月影老师说过的一句话,不要问前端学不学算法。计算机学科的每一位都有必要了解算法,有写出高质量代码的潜意识

一、问题描述

给你一个包含 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]
输出:[]

二、思路讲解

这里借用代码随心录大佬的动图

15.三数之和.gif

迭代 + 双指针

排序 为什么要排序? 可以节省掉一部分的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
};

后续

好了,本篇 力扣-三数之和 到这里就结束了,我是邵小白,一个在前端领域摸爬滚打的大三学生,欢迎👍评论。