Skip to content
本页目录

15.三数之和

题目描述

注意

  • 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0

  • 请你返回所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组

示例

  • 输入:nums = [-1,0,1,2,-1,-4]

  • 输出:[[-1,-1,2],[-1,0,1]]

  • 解释:

    • nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0
    • nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0
    • nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0
  • 不同的三元组是 [-1,0,1][-1,-1,2]

  • 注意,输出的顺序和三元组的顺序并不重要。

思路

  • 首先对数组进行从小到大排序

  • 遍历数组,如果当前元素大于 0 终止循环 因为数组是从小到大排序过的

  • if (i > 0 && nums[i] == nums[i - 1]) continue; 这是为了去重,排序后可能会存在连续相等的元素

  • 定义两个指针 L 、 R 分别指向当前遍历元素的右一位和数组最后一位

  • 满足 L < R 的条件下

    • 如果 nums[i] + nums[L] + nums[R] === 0[nums[i], nums[L], nums[R]] 存入结果集 ans 中,同时对左右两边分别去重处理,然后分别把左指针右移一位、右指针左移一位
    • 如果 nums[i] + nums[L] + nums[R] > 0 将右指针左移一位
    • 如果 nums[i] + nums[L] + nums[R] < 0 将左指针右移一位
  • 最后返回结果集

代码

js
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function (nums) {
  let ans = []; // 存放结果集
  const len = nums.length;
  if (!nums || len < 3) return [];
  nums.sort((a, b) => a - b);
  for (let i = 0; i < len; i++) {
    if (nums[i] > 0) break; // 如果当前元素大于 0 终止循环求解【因为数组是从小到大排序过的】
    if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
    let L = i + 1,
      R = len - 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 + 1] === nums[L]) L++;
        while (L < R && nums[R - 1] === nums[R]) R--;
        L++;
        R--;
      } else if (sum > 0) {
        R--;
      } else {
        L++;
      }
    }
  }
  return ans;
};

MIT Licensed