三数之和(LeetCode)

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

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

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

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

'''

这道题因为涉及到好几个步骤,比较有难度。

我一开始是想按两数之和的思路暴力过,但是呢,明显这是行不通的。

后来受到大佬的点拨,回去看了一下两数之和的解题思路。

发现其实也是可以套用到里面的。

然后发现最后几个测试用例真的反人类。。

长度在3000左右,所以没有好好处理的话,很容易超时。

emmmm。。。虽然过了,但是是卡线过的,所以到最后我会膜拜一下大佬的代码

'''

class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if len(nums)<3: return []#长度小于三,无解
        nums = sorted(nums)#排序
        if nums[0]==nums[-1] and nums[0]==0:return [[0,0,0]]#排序完后,全等于零的话,就只有一个答案

        if nums[0]==nums[-1] and nums[0]!=0:return [] #同理,全等于任意非零的一个数的话,没有答案
        lis = []
        dic = {}
        for i in range(len(nums)):#构造表
            if nums[i] not in dic:
                dic[nums[i]] = i


        for target in range (len(nums)):#将nums遍历一次,且把nums[target]的值看做两数之和的target
            for i in range (target+1,len(nums)):#找其它两个数字
                    q = -(nums[target] + nums[i])
                    w = nums[target]
                    e = nums[i]
                    if q in dic and dic[q] != i and dic[q] != target:
                        lis.append(sorted([w,e,q]))#先把它们放进去,不管重复,然后在最后去重。试过在这里去重然后超时了。。
        turn_list = []#最后返回的数组
        dic = {}
        for i in lis:
            if str(i) not in dic:
                dic[str(i)] = 1
                turn_list.append(i)
        return turn_list

'''

最后来膜拜一下大佬的解法

class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res=[]
        d=dict()
        for i in nums:
            if i not in d:
                d[i]=0
            d[i]+=1  #统计数字出现的次数,也是变相的去重了
        posnum=[i for i in d  if i>0 ]#i in d的意思跟 i in d.keys()的效果差不多
        negnum=[i for i in d  if i<0 ]#分开正负
        if d.get(0,0)>2:#这里的get有两个参数,第一个0是在关键字中查找返回关键字为0的值(即返回统计到0的个数),第二个0的意思是,如果没有这个关键字就返回0。这是算比较高级的用法了。也可以这样if (0 in d.keys() and d[0]>2):res.append[[0,0,0]]
            res.append([0,0,0])#如果0的个数多于3个,就加一个解进取。能解决倒数第二个测试例超级多0的问题
        if negnum==[] or posnum==[]:#显然,全负或全正都是没有答案的,所以return 了
            return res
        for i,x in enumerate(posnum):#遍历posnum,得到posnum的下标和数字
            if d[x]>=2 and -2*x in d:# 把符合这个等式的放进去x + x + (- 2 * x) = 0
                res.append([x,x,-2*x])
            for y in posnum[i+1:]:#把符合 x + y + (-(x+y)) = 0 放进res
                if -(x+y) in d:
                    res.append([x,y,-x-y])
        for i,x in enumerate(negnum):同上理
            if d[x]>1 and -2*x in d:
                res.append([x,x,-2*x])  
            for y in negnum[i+1:]:
                if -(x+y) in d:
                    res.append([x,y,-x-y])
        
        if 0 in d:#如果d中有0,就看一看是不是存在相反数
            for x in posnum:
                if -x in d:
                    res.append([x,0,-x])
        return res

'''

猜你喜欢

转载自blog.csdn.net/weixin_41169182/article/details/85056172