原文:15. 三数之和(力扣 面试题) - 每天一个JavaScript小知识@Js中文网 · 码农进阶题库

原文地址:https://www.javascriptc.com/interview-tips/zh_cn/leetcode/leetcode-javascript-solution-015/

题目:

难度:Middle

相关话题:数组双指针

给定一个包含 n 个整数的数组 nums ,判断 nums 中是否存在三个元素 a,b,c , 使得a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意: 答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

思路:

最优解的时间复杂度是O(N^2),排序是为了能避免没有必要的计算。

遍历nums,如果当前数字是nums[i],那么另外2个数的和就是-nums[i],由于是有序的,可以使用双指针,一个头i,一个尾j

如果当前和>0,说明需要减小,因此j--,相反则i++

如果相等则添加到结果,额外还需要去重。

/**
 * @来源: Javascript中文网 - 前端进阶资源教程 https://www.javascriptc.com/
 * @介绍:一个致力于帮助开发者用代码改变世界为使命的平台,每天都可以在这里找到技术世界的头条内容
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function(nums) {
  nums.sort((a,b)=>a-b)
  let result=[]
  for(let i=0;i<nums.length-1;i++){
    if(i>0 && nums[i]===nums[i-1])continue
    let lo=i+1,hi=nums.length-1,target=-nums[i]
    while(lo<hi){
      if(nums[lo]+nums[hi]===target){
        result.push([nums[i],nums[lo],nums[hi]])
        while(nums[lo]===nums[lo+1])lo++
        while(nums[hi]===nums[hi-1])hi--
        lo++;hi--
      }else if(nums[lo]+nums[hi]<target){
        lo++
      }else{
        hi--
      }
    }
  }
  return result
};

#### 扩展阅读: