leetcode(35)----- 三数之和

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

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

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

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

思路分析:

1.要找到相加和为0的三个数,可用多重循环来做,这种方法的时间复杂度是O(n^3),空间复杂度为O(1).提交之后提示超出时间限制。

Python代码实现:

class Solution(object):
    def threeSum(self, nums):
        three = []
        for i in range(0,len(nums)):
            for j in range(i+1,len(nums)):
                for k  in range(j+1,len(nums)):
                    if nums[i]+nums[j]+nums[k]==0:
                        a = sorted([nums[i],nums[j],nums[k]])
                        if a not  in three:
                            three.append(a)
        return (three)

2.试一试去掉一层循环,改为双重循环。结果仍是超出时间限制。

class Solution(object):
    def threeSum(self, nums):
        three = []                  #建立一个空列表存放三元组
        nums = sorted(nums)             #将数组排序
        for i in range(0, len(nums)):
            for j in range(i + 1, len(nums)):
                a = -(nums[i] + nums[j])
                if a in nums[j+1:]:            #查找以后的数,防止之前的数重用
                    b = nums[j+1:].index(a)+j+1
                    if b > j:
                        c = sorted([nums[i], nums[j], nums[b]])
                        if c not in three:             #重复的三元组不添加
                            three.append(c)
        return three

3.百度了一下这道题,别人的思路是:先对数组排序,然后开始遍历,对于数组中的每一个元素,用两指针往中间夹,直到找出所有的解。

也可理解为先排序,从小到大选取第一个数,再在剩余区间左右夹击,找到符合条件的。时间复杂度为 O(n^2).

类似与二叉搜索,只是每次往中间进一位。

实现

class Solution(object):
    def threeSum(self, nums):
        three_list = []            # 存储结果列表
        nums = sorted(nums)              # 对nums列表进行排序,无返回值,排序直接改变nums顺序
        for i in range(len(nums)):           # 如果排序后第一个数都大于0,则跳出循环,不可能有为0的三数之和
            if nums[i] > 0:
                break
            if i > 0 and nums[i] == nums[i-1]:              # 排序后相邻两数如果相等,则跳出当前循环继续下一次循环,相同的数只需要计算一次
                continue
            j = i + 1            # 记录i的下一个位置
            k = len(nums) - 1             # 最后一个元素的位置
            while j < k:
                if nums[j] + nums[k] == -nums[i]:            # 判断三数之和是否为0
                    three_list.append([nums[i], nums[j], nums[k]])           # 把结果加入数组中
                    while j < k and nums[j] == nums[j+1]:                # 判断j相邻元素是否相等,有的话跳过这个
                        j += 1
                    while j < k and nums[k] == nums[k-1]:           # 判断后面k的相邻元素是否相等,是的话跳过
                        k -= 1             
                    j += 1              # 没有相等则j+1,k-1,缩小范围
                    k -= 1   
                elif nums[j] + nums[k] < -nums[i]:               # 小于-nums[i]的话还能往后取
                    j += 1
                else:
                    k -= 1
        return three_list

之前的类似题:两数之和

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值