15. 三数之和

分手后的思念是犯贱 2022-10-30 12:26 234阅读 0赞
题目描述:

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

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

示例 1:
  1. 输入:nums = [-1,0,1,2,-1,-4]
  2. 输出:[[-1,-1,2],[-1,0,1]]
示例 2:
  1. 输入:nums = []
  2. 输出:[]
示例 3:
  1. 输入:nums = [0]
  2. 输出:[]
提示:
  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105
题解:

方法一:暴力解法

题目中要求找到所有「不重复」且和为 0 的三元组,这个「不重复」的要求使得我们无法简单地使用三重循环枚举所有的三元组。这是因为在最坏的情况下,数组中的元素全部为 0,即

  1. [0, 0, 0, 0, 0, ..., 0, 0, 0]

任意一个三元组的和都为 0。如果我们直接使用三重循环枚举三元组,会得到 O(n3)个满足题目要求的三元组(其中 NN 是数组的长度)时间复杂度至少为 O(n3)。在这之后,我们还需要使用哈希表进行去重操作,得到不包含重复三元组的最终答案,又消耗了大量的空间。这个做法的时间复杂度和空间复杂度都很高,因此我们要换一种思路来考虑这个问题。

时间复杂度:O(n3)

方法二:排序 + 双指针

  • 利用排序避免重复答案
  • 利用双指针找到所有解

时间复杂度:

  • 排序O(nLogn)
  • 搜索解O(n2)

    /* @param {number[]} nums @return {number[][]} /
    var threeSum = function(nums) {
    nums.sort((a, b) => a - b) // 升序

    const result = []
    const len = nums.length

    for(let i = 0; i < len - 2; i ++) {

    1. if(nums[i] === nums[i - 1]) { // 有连续相同的值,直接跳过
    2. continue
    3. }
    4. let left = i + 1
    5. let right = len - 1
    6. while(left < right) {
    7. let sum = nums[i] + nums[left] + nums[right]
    8. if(sum === 0) {
    9. // 此处使用后++ --做双指针+-,因为此处等式成立,需同时给左指针+1,右指针-1
    10. result.push([nums[i], nums[left++], nums[right--]])
    11. while(nums[left] === nums[left - 1]) { // 有连续相同的值,一样跳到下一个
    12. left ++
    13. }
    14. while(nums[right] === nums[right + 1]) { // 有连续相同的值,跳到上一个
    15. right --
    16. }
    17. } else {
    18. if(sum < 0) {
    19. left ++
    20. } else {
    21. right --
    22. }
    23. }
    24. }

    }
    return result
    };

发表评论

表情:
评论列表 (有 0 条评论,234人围观)

还没有评论,来说两句吧...

相关阅读

    相关 15.之和

    [题目][Link 1] 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足

    相关 15. 之和

    链接:https://leetcode-cn.com/problems/3sum 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,

    相关 15.之和

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