Leetcode-15-三数之和

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

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
解法一:Leetcode上目前用时最短的

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """

        # res = []
        # nums.sort()#先排序可以去重复
        # length = len(nums)
        # for i in xrange(length-2): #最后的两个,和倒数第三个组成组合
        #     if nums[i]>0: 
        #         break #因为已经排序了,所以到大于零的位置,之后的数字都是大于零的,肯定没有符合条件的组合了
        #     if i>0 and nums[i]==nums[i-1]: 
        #         continue #这种就是说,前面已经尝试过,如果成功了这次会重复,没成功,这次也没必要做了
        #     l, r = i+1, length-1 #双指针开始遍历
        #     while l<r:
        #         total = nums[i]+nums[l]+nums[r]
        #         if total<0: #因为排序了,所以如果小于零,那么我们移动到更大的地方
        #             l+=1
        #         elif total>0: #排序的,所以我们往更小的方向移动
        #             r-=1
        #         else: #等于0符合要求
        #             res.append([nums[i], nums[l], nums[r]])
        #             #方式重复操作,左右都移动到不重复的数字
        #             while l<r and nums[l]==nums[l+1]: #[6]
        #                 l+=1
        #             while l<r and nums[r]==nums[r-1]: #[6]
        #                 r-=1
        #             l+=1
        #             r-=1
        # return res
    
        # a+b+c = 0
        # a+b = -c
        num_dict = {}
        res = []

        for i in nums:
            if i in num_dict:
                num_dict[i] += 1
            else:
                num_dict[i] = 1

        pos = [i for i in num_dict if i>0]
        neg = [i for i in num_dict if i<0]
        neg.sort()
        #特殊情况的妙用
        if 0 in num_dict and num_dict[0]>=3:
            res.append([0,0,0])
        for i in pos:
            for j in neg:
                k = -i-j
                if k in num_dict:
                    if (k==i or k==j) and num_dict[k]>=2:
                        res.append([i,k,j])
                    elif j<k<i:
                        res.append([i,k,j])
                    if k<j:
                        break
        return res

解法二: 来源于https://www.twblogs.net/a/5c4b2590bd9eee6e7e06c45e/zh-cn

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()    #先对数组进行排序
        res = []
        for i in range(len(nums)-2):    #先确定第一个数,因为总共要有3个数,所以只能循环至倒数第三个数
            if i > 0 and nums[i] == nums[i-1]:    #如果后面的数和前面的相同,为避免重复答案,跳过这次循环
                continue
            j = i + 1;k = len(nums) - 1    #对剩下的两个数设置首尾指针
            while j < k:
                s = nums[i] + nums[j] + nums[k]
                if s < 0:
                    j = j + 1    #当前和比0小,需要增加当前的和,j右移
                elif s > 0:
                    k = k - 1    #当前和比0大,需要减小当前的和,k左移
                else:
                    res.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 = j + 1;k = k -1    #上面的操作结束后,两个指针所指的值只是位于相同值的末端,值本身没有变化本身,需要继续移动到不同数字上
        return res

解法三:https://www.cnblogs.com/chruny/p/4820473.html

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        size = len(nums)
        ans = []
        if size <= 2:
            return ans
        nums.sort()
        i = 0
        while i < size -2:
            tmp = 0 - nums[i]
            j = i + 1
            k = size -1
            while j < k:
                if nums[j] + nums[k] < tmp:
                    j += 1
                elif nums[j] + nums[k] > tmp:
                    k -= 1
                else:
                    ans.append([nums[i],nums[j],nums[k]])
                    j += 1
                    k -= 1
                    while j < k:
                        if nums[j] != nums[j - 1]:
                            break
                        if nums[k] != nums[k + 1]:
                            break
                        j += 1
                        k -= 1
            i += 1
            while i < size - 2:
                if nums[i] != nums[i - 1]:
                    break
                i += 1
        return ans
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值