python Solution LeetCode No.15 ThreeSum(三数之和)

题目:

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

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

示例:

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

代码:

class Solution:
    def threeSum(self, alist):
        resultlist = []
        numsset = set()
        alist.sort()
        target = 0
        for x in alist:
            numsset.add(x)
        for i, j in enumerate(alist[:-2]):
            used_nums_set = set()
            if j > target/3:
                break
            elif i > 0 and j == alist[i-1]:
                continue
            for l, k in enumerate(alist[i+1:-1]):
                if k > (target-j)/2:
                    break
                elif l > 0 and k == alist[l+i]:
                    continue
                if alist[l+i+1:].count(k) < 2:
                    used_nums_set.add(k)
                if -(j+k) in numsset and -(j+k) not in used_nums_set:
                    used_nums_set.add(-(j+k))
                    resultlist.append([j, k, -(j+k)])
            numsset.remove(j)
        return resultlist

结果:

311 / 313 个通过测试用例,在312测试用例时超时,该测试用例输入值数量为3000,在本地执行时间为89秒,确实是慢点,留个思路吧

说明:

1.代码功能实现上本身没有问题,在312用例的大量值的情况下超时,由于时间复杂度是O(N平方)的,空间复杂度是O(N)得,比较耗时的部分为列表排序及嵌套循环

2.使用set替代了第三重嵌套循环

3.排序后,列表是从小到大的顺序,由于题目是a+b+c=target,即a+b+c=0,所以a的最大值为target/3,超出部分就不用找了,所以break,对于相同的a值,由于首次循环已经取得了所有可能的值,故只循环一次,多余的跳过,以上操作用于节约一部分时间

4.在固定a值后,循环b值,此时b的最大值为(target - a)/2,操作同a.

5.初始化两个set,一个用于存放列表中所有的值(numsset),另一个(used_nums_set)初始为空但每次循环b值时,存放找到的结果c值,而在a值的一重循环完成后,将a值从 numsset删除,以上操作均以去重为目的

6.固定a值后,b连续出现次数小于2时,则在a的单次循环不能重复使用,判断c值前,需将其提前加入(used_nums_set),否则会出现错误解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值