LeetCode三数之和 | 算法练习系列

200 阅读3分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

前言

在看到这道算法题的题目时,我第一感觉就是简单,不就三个数相加,应该和之前做过的两数之和差不多,通过map轻松拿下,但事实并不是这样的,这个题和之前的两数之和半毛钱关系都没有。。。

题目描述

给你一个包含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]

输出:[]

解题思路

  • 首先从题目入手,答案中不能包含重复的三元组,那么我们判断的范围直接判断到小于nums.length-2即可,也就是当输入数组长度小于3的时候直接输出[]
  • 这道题刚拿到手的时候是无从下手的,可以先通过sort排序来把输入数组进行排序,这样看起来思路就清晰了,我们可以从前那个数也就是i,再拿个数i+1,当做start,从尾部拿个数,当做end,这三个数相加和0比较,如果等于0则存入我们的结果数组,如果小于0,则start++,如果大于0,则end--,知道start<end不成立为止
  • 但有一次成立并存入结果之后,我们这时要同时进行start++,end--
  • 还有一个重要的点,当进行start++和end--的时候一定要和前一个值进行判断,如果不判断就会存在重复的三元数组了
  • 这道题非常重要的两点就是,首先排序(这是思想),然后就是时刻去重,首先再每次循环的时候要对nums[i]和nums[i-1]进行比较,相同就跳过,这时去重,其次是start++和end--的时候再次去重,这样得到的结果就是没有重复的三元组了
  • 直接来代码,如下
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function(nums) {
    const result =[]
        nums.sort(function(a,b){
            return a-b
        })
        for(let i=0;i<nums.length -2;i++){
            if(nums[i] !==nums[i-1]){ //这里是第一次去重
                let start = i+1
                let end = nums.length-1
                while(start<end){
                    if(nums[i]+nums[start]+nums[end]===0){
                        result.push([nums[i],nums[start],nums[end]])
                        start++
                        end--
                        while(start<end && nums[start]===nums[start-1]){ //这里是第二次去重
                            start++
                        }
                        while( start<end &&nums[end]===nums[end+1]){ //这里是第二次去重
                            end--
                        }
                    }else if(nums[i]+nums[start]+nums[end]<0){
                        start++
                    }else{
                        end--
                    }
                }

            }

        }
        return result
           
};

总结

本题主要思想就是通过排序从大到小排列,然后通过双重去重来得到结果,这题还是很有巧劲的,如果用暴力必会超时,LeetCode运行结果如下:

三数之和.PNG 如果xdjmm有更好的见解,欢迎分享出来。