三数之和_LeetCode [15]

题目描述

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

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

解题思路

可以采用排序+双指针,利用双指针前后遍历排序后的数组,找到和为零的元素加入到空列表中

代码

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
    #若给定的数组为空,返回空列表
        if not nums:
            return []
    #对数组进行排序操作,便于后续前后指针的移动
        nums.sort()
    #定义一个空列表来存储满足条件的三元组
        res = []
        n = len(nums)
    # 遍历数组
        for i in range(n-2):
    #如果数组前后元素相同,则跳过
            if i>0 and nums[i] == nums[i-1]:
                continue
    #定义左右指针,分别从两头向中间遍历   
            l = i + 1
            r = n - 1
            while l < r:
    #左指针要始终小于右指针,下面的分析分为了三种情况:和为零,和大于零,和小于零
                if nums[i] + nums[l] + nums[r] == 0:
    # 满足条件,加入列表,注意格式
                    res.append([nums[i], nums[l], nums[r]])
    # 和为零时,继续查找,判断是否有相邻相同的元素,继续移动指针
                    while l < r and nums[l] == nums[l+1]:
                        l = l + 1
                    while l < r and nums[r] == nums[r-1]:
                        r = r-1
    # 查找所有满足条件的三元组
                    l = l + 1
                    r = r - 1
    # 大于零时,右指针左移,否则,左指针右移
                elif nums[i] + nums[l] + nums[r] > 0:
                    r = r - 1
                else:
                    l = l + 1
    # 返回存储满足条件三元组的列表
        return res

提交结果
在这里插入图片描述

复杂度分析

时间复杂度: O ( n 2 ) O\left(n^{2}\right) O(n2),数组排序 O ( N log ⁡ N ) O(N \log N) O(NlogN),遍历数组 O ( n ) O\left(n\right) O(n),双指针遍历 O ( n ) O\left(n\right) O(n),总体 O ( N log ⁡ N ) + O ( n ) ∗ O ( n ) , O ( n 2 ) O(N \log N)+O\left(n\right)*O\left(n\right),O\left(n^{2}\right) O(NlogN)+O(n)O(n)O(n2)
空间复杂度: O ( 1 ) O(1) O(1)

作者:wu_yan_zu
链接:https://leetcode-cn.com/problems/3sum/solution/pai-xu-shuang-zhi-zhen-zhu-xing-jie-shi-python3-by/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

后续思考

总感觉好像还是多遍历了一些东西,比如 i i i 向后移动,左指针 l l l 也在向后移动,由于 l = i + 1 l = i+1 l=i+1 ,不可避免的会出现多次遍历的情况,就像递归中的重复计算问题,可否有好的解法优化一下?比如加个字典或者备忘录?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值