(javaScript)leetcode每日一题 - 15. 三数之和

520 阅读1分钟

leetcode每日一题 - 15. 三数之和

image.png

题解

给数组进行排序,排序后固定一个数nums[i],再使用左右指针向nums[i]后面的两端,数字分别为nums[L]和nums[R],计算三个数的和sum是否满足为0,满足则添加进结果集
下面是边界条件
(1)如果nums[i]大于0,则三数之和必然无法等于0,则结束循环break
(2)如果nums[i] === nums[i - 1],则说明i重复,所以要跳出该循环进入到下一个循环
(3)当sum == 0时,nums[L] === nums[L + 1],会导致结果重复,应该用while循环判断,跳过(L ++)
(4)同理,当sum == 0时,nums[R] === nums[R - 1],会导致结果重复,应该用while循环判断,跳过(R --)

贴出代码

// 4.15 三数之和
  const nums: number[] = [-1, 0, 1, 2, -1, -4]

  function threeSum(nums: number[]): number[][] {
    const ans: number[][] = []
    if (nums === null || nums.length < 3) return ans
    // 从小到大排序(升序)(假设a为1,b为2,a - b为升序)
    nums.sort((a, b) => a - b)
    // 前提须知,break是跳出循环,continue是跳出当前循环到下一个循环
    for (let i = 0; i < nums.length; i++) {
      // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
      if (nums[i] > 0) break
      // 去重(从第二个i开始,i对应的值等于i的上一个值,则跳出当前循环)
      if (i > 0 && nums[i] === nums[i - 1]) continue
      let L = i + 1
      let R = nums.length - 1
      while (L < R) {
        const sum = nums[i] + nums[L] + nums[R]
        if (sum === 0) {
          ans.push([nums[i], nums[L], nums[R]])
          while (L < R && nums[L] == nums[L + 1]) L++ // L去重
          while (L < R && nums[R] == nums[R - 1]) R-- // R去重
          L++
          R--
        } else if (sum < 0) {
          L++
        } else if (sum > 0) {
          R--
        }
      }
    }
    return ans
  }