LeetCode ----15三数之和

前言

对力扣题目“三数之和”的一些思考


一、题目

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

注意:答案中不可以包含重复的三元组。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum

二、解法

1.暴力解法

class Solution():
    def answer(self,nums):
        nums.sort()
        result = set()
        for i in range(len(nums)):
            for j in range(i+1,len(nums)) :
                for y in range(j+1,len(nums)):
                    if nums[i]+nums[j]+nums[y] == 0 :
                        result.add((nums[i],nums[j],nums[y]))
                        
        return list(result)
      #  315/318  over time ...  

2.指针移动

先循环一个,然后两个指针在剩余的数中分别由ZUO 右向中间汇集:

class Solution():
    def answer(self,nums):
        nums.sort()
        result = set()
        for i in  range(len(nums)-2):
            p = i+1
            q = len(nums) - 1
            while q > p :
                if nums[i] + nums[p] + nums[q] == 0 :
                    result.add((nums[i],nums[p],nums[q]))
                if nums[i] + nums[p] + nums[q] < 0 :
                    p += 1
                else :
                    q -=1
        return list(result)
 # Run time: 4104ms Memory consump:16.7MB

这个写的有点糙,看完这个答案之后:
链接:https://leetcode-cn.com/problems/3sum/solution/pai-xu-shuang-zhi-zhen-zhu-xing-jie-shi-python3-by/
作者:wu_yan_zu
基于原来写出的加了一些判断条件,从而在明知后面无解的情况下,不再继续循环:

class Solution():
    def answer(self,nums):
        nums.sort()
        result = set()
        for i in  range(len(nums)-2):
            if nums[i] > 0 :
                return list(result) 
                #排序之后,起始值都大于零,那么后面肯定无解
            if (i>0 and nums[i]==nums[i-1]):
                continue       
                #意在去重
            p = i+1
            q = len(nums) - 1
            while q > p :
                if (nums[i] + nums[p] + nums[q]) == 0 :
                    result.add((nums[i],nums[p],nums[q]))
                    while (q > p) and (nums[q] == nums [q-1]):
                        q -= 1
                    while (q > p) and (nums[p] == nums [p+1]):
                        p += 1
                    #去重
                    p += 1
                    q -= 1
                elif nums[i] + nums[p] + nums[q] > 0 :  #确定指针移动方向
                    q -= 1
                else :
                    p +=1
        return list(result)
      #Run time:820ms Mermory consump: 16.8MB

改动之后的运行时间和参考的差不多,但改动之后的内存占用略少.

尝试两个循环,一个指针:

class Solution():
    def answer(self,nums):
        nums.sort()
        result = set()
        for i in range(len(nums)-2):
            if nums[i] > 0 :
                return list(result)
            for j in range(i+1,len(nums)-1):
                q = len(nums) - 1
                now = nums[i] + nums[j]
                if now > 0:
                    break
                while q > j :
                    if now + nums[q] == 0 :
                        result.add((nums[i],nums[j],nums[q]))
                        q -= 1
                    if now + nums[q] > 0 :
                        q -= 1 
                    else :
                        break
        return list(result)
# 315/318   over time ....

这个好像也是立方次的时间复杂度。

3.递归

仿照上一篇的两数之和的递归,很容易照猫画虎把三数之和的递归写出来:

class Solution():
    def answer(self,nums):
        nums.sort()
        result = []

        def find(i,target,oneSolution,notSelected):
            if len(oneSolution) == 3 and target == 0:
                result.append(oneSolution)
                return
            if i >= len(nums) or len(oneSolution) > 3 :
                return
            if target - nums[i] - (2-len(oneSolution))*nums[-1] > 0 or nums[i] in notSelected :
                find(i+1,target,oneSolution,notSelected)
            elif target - (3-len(oneSolution))*nums[i] < 0 :
                return
            else:
                find(i+1,target,oneSolution,notSelected+[nums[i]])
                find(i+1,target-nums[i],oneSolution+[nums[i]],notSelected)
        find(0,0,[],[])
        return result
# 315/318 over time...

然而也超时了。
不知道是不是我中间判断条件有缺少思考的地方,如果有看出来的大神们,还请不吝赐教。

总结

三数之和虽然看起来和二数之和很类似,但是它们之间的差异还是蛮大的。

你可能感兴趣的:(Leetcode,python,leetcode,指针)