LeetCode 15 3Sum(Tag: Array Difficulty:Medium)

题目描述

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

链接:leetcode-cn.com/problems/3s…

题解

  1. 暴力解法,从0位置开始依次遍历每个位置上的元素,存在三个元素的和为0时,加入一个 set 中,防止重复,此方法的时间复杂度为 O(n³)
  2. 如果我们每次固定一个元素a,那么问题转换为 leetcode 1 2sum的问题,在剩余的元素中求两个元素和为 -a 的组合。这里我们采用双指针来找这两个元素,由于题目要求不重复三元组,可以采用先将数组排序的方法,过滤掉相同的元素,同时排序好的数组可以用来减枝。此方法的时间复杂度为 O(n²)
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function (nums) {
  if (nums.length < 3) {
    return [];
  }
  let ans = [];
  nums = nums.sort((a, b) => a - b);
  for (let index = 0; index < nums.length - 2; index++) {
    if (nums[index] > 0) break; // 减枝,当前元素已经大于0时,无需再遍历
    if (index > 0 && nums[index - 1] === nums[index]) {
      continue;  // 排除相同元素,防止答案重复
    }
    const element = nums[index];
    let l = index + 1;
    let r = nums.length - 1; // 双指针
    while (l < r) {
      if (element + nums[l] + nums[r] === 0) {
        ans.push([element, nums[l++], nums[r--]]);
        while (l < r && nums[l] === nums[l - 1]) { // 排除相同元素,防止答案重复
          l++;
        }
        while (l < r && nums[r] === nums[r + 1]) { // 排除相同元素,防止答案重复
          r--;
        }
      } else if (nums[l] + nums[r] + element > 0) {
        r--;
      } else {
        l++;
      }
    }
  }
  return ans;
};
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享