(python版) Leetcode-15.三数之和

01 题目:三数之和

链接:https://leetcode-cn.com/problems/3sum
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

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

示例
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:

[
  [-1, 0, 1],
  [-1, -1, 2]
]

02 解析

  1. 先从小到大排序:sort()函数
  2. 参数初始化:k从0到 len(nums)-2就够了,题里说的是a,b,c三个不同的数;i=0,j=len(nums)-1开始
  3. 保持指针k蓝色)不动:先移动指针 i (小->大 橙色),移动指针 j(大->小 绿色)
    并计算三个数的和 sum 判断是否满足为 0,满足则添加进结果集
  4. 判断+去重
    第一个if:如果 nums[ k ]大于 0,则三数之和一定 0,结束循环
    第二个if:如果 nums[ k ] = nums[ k-1 ],则说明该数字重复,会导致结果重复,所以应该跳过
    第三个if:计算sum
        当 sum < 0 时, i++;若nums[ i ]= nums[ i+1 ],则会导致结果重复,应该跳过,i++
        当 sum > 0 时, j–;若nums[ j ]= nums[ j-1 ] 则会导致结果重复,应该跳过,j−−
        同理,当 sum = 0 时,res.append([nums[k], nums[i], nums[j]])
              若 nums [i ]= nums[ i+1 ]则会导致结果重复,应该跳过,i++
              若 nums[ j ]= nums[ j-1] 则会导致结果重复,应该跳过,j−−
    在这里插入图片描述
    时间复杂度:O(n2),n 为数组长度

03 代码

def threeSum(nums):
    nums.sort() # 排序
    res, k = [], 0
    for k in range(len(nums) - 2):
        if nums[k] > 0: break # 1. because of j > i > k.
        if k > 0 and nums[k] == nums[k - 1]: continue # 2. skip the same `nums[k]`.
        i, j = k + 1, len(nums) - 1
        while i < j: # 3. double pointer
            s = nums[k] + nums[i] + nums[j]
            if s < 0:
                i += 1
                while i < j and nums[i] == nums[i - 1]: i += 1
            elif s > 0:
                j -= 1
                while i < j and nums[j] == nums[j + 1]: j -= 1
            else:
                res.append([nums[k], nums[i], nums[j]])
                i += 1
                j -= 1
                while i < j and nums[i] == nums[i - 1]: i += 1
                while i < j and nums[j] == nums[j + 1]: j -= 1
    return res
    # 作者:jyd
    # 链接:https://leetcode-cn.com/problems/3sum/solution/3sumpai-xu-shuang-zhi-zhen-yi-dong-by-jyd/

自个第一次写这个函数的时候,没考虑到去重,而是在得出所有符合三数之和为0的组合后,才去重的。
故记录一下在嵌套列表中去重的方法

'''
嵌套列表去重方法
直接看[22]会有点懵,先看20, 它将a的每个小列表先转成元组,再去重,然后变成列表
再看[22],后半部分是完成了元组-去重,前部分将每个小元组变成列表,再变成大列表,
但是是乱序的
最后是[25],sort方法通过参数key指定索引值,故指定a的下标,根据这个索引,对new列表进行排序
'''
In [19]: a = [[0,0,0,],[4,2,5],[1,8,6],[0,0,0],[5,3,9],[4,2,5]]

In [20]: new = list(set(tuple(i) for i in a))

In [21]: new
Out[21]: [(5, 3, 9), (4, 2, 5), (0, 0, 0), (1, 8, 6)]

In [22]: new = [list(t) for t in set(tuple(i) for i in a)]

In [23]: new
Out[23]: [[5, 3, 9], [4, 2, 5], [0, 0, 0], [1, 8, 6]]

In [24]: new.sort(key = a.index)

In [25]: new
Out[25]: [[0, 0, 0], [4, 2, 5], [1, 8, 6], [5, 3, 9]]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值