春招打卡|三数之和

69 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

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

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

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

二、思路分析

  1. 三数之和是两数之和的后续题目,首先考虑暴力方式解决此题,由于要枚举三个数,暴力方式的时间复杂度为O(n3)。考虑到需要去除重复的结果,对数组进行排序,使用内置的快排sort.Ints函数,并且在每层循环中加入nums[x]==nums[i-1] { continue }避免重复。
  2. 一种更有效率的方式是,将第三层k循环改变为双指针的方式,即枚举第二个数和第三个数的时候为两个指针,一个正向遍历,一个从后向前。这样复杂度降低为O(n),第一个指针向后移动时,后一个指针向前移动,即可遍历到符合条件的结果,两层的遍历总共会遍历O(n)的时间复杂度,当两个相同时使其跳出循环,即代码中j == k { break }

三、AC 代码

暴力破解

func threeSum(nums []int) (ans [][]int) {
    sort.Ints(nums)
    for i := 0;i<len(nums);i++ {
        //去重
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        for j := i+1 ;j<len(nums);j++ {
            if j > i + 1 && nums[j] == nums[j-1] {
                continue
                }
                for k := j + 1 ;k<len(nums);k++ {
                    if k > j +1 && nums[k] == nums[k-1]{
                        continue
                    }
                    if nums[j] + nums[k] + nums[i] == 0 {
                        ans = append(ans,[]int{nums[i],nums[j],nums[k]})
                    }
                }
            }
        }
         return ans
    }

双指针做法

func threeSum(nums []int) (ans [][]int) {
    sort.Ints(nums)
    for i := 0;i<len(nums);i++ {
        //去重
        if i > 0 && nums[i] == nums[i-1] {
            continue
        }
        k := len(nums) - 1
        for j := i+1 ;j<len(nums);j++ {
            //去重
            if j > i + 1 && nums[j] == nums[j-1]{
                continue
            }
            //k在最右边
            for j < k &&  nums[j] + nums[k] +nums[i] > 0 {
                k--
            }
            if j == k {
                break
            }
            if nums[j] + nums[k] + nums[i] == 0 {
                ans = append(ans,[]int{nums[i],nums[j],nums[k]})
            }
        }
    }
    return ans
}

四、总结

当需要枚举数组中两个元素时,第一个元素递增,第二个元素递减时,就可以考虑双指针做法。如本题中,枚举的第一个数是确定的,目标值也是确定的,则第二个数和第三个数一个增加另一个就要递减。