failed LeetCode 15. 3Sum

三数之和

先锁定前两个,第三个游标查后面的,之后再前进第二个游标。到末尾再前进第一个游标。

first submission
class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        rList=[]
        ai=0
        bi=ai+1
        ci=ai+2

        ll=len(nums)-1

        while ci<ll: 
            c=0-nums[ai]-nums[bi]
            while ci<ll:
                if nums[ci]==c:
                    oneList=sorted([nums[ai],nums[bi],nums[ci]])
                    if oneList not in rList:
                        rList.append(oneList)
                ci+=1
            bi+=1
            ci=bi+1

        return rList

Wrong Answer:

Input:
    [0,0,0]
Output:
    []
Expected:
    [[0,0,0]]

边界忘了算上

Input:
    [3,0,-2,-1,1,2]
Output:
    [[-2,-1,3]]
Expected:
    [[-2,-1,3],[-2,0,2],[-1,0,1]]

没移动a游标

second submission
class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        rList=[]
        ai=0
        bi=ai+1
        ci=ai+2

        ll=len(nums)

        while ci<ll: 
            c=0-nums[ai]-nums[bi]
            while ci<ll:
                if nums[ci]==c:
                    oneList=sorted([nums[ai],nums[bi],nums[ci]])
                    if oneList not in rList:
                        rList.append(oneList)
                ci+=1

            bi+=1
            ci=bi+1

            if ci==ll:
                # end is move a  
                ai+=1
                bi=ai+1
                ci=ai+2
                

        return rList

Time Limit Exceeded:命名为测试点2

Last executed input:
[3,13,8,-8,-15,-3,13,-3,-12,-7,2,-3,-8,10,0,-12,5,13,13,8,6,-11,6,-10,-13,14,-9,9,5,7,12,-14,5,-3,-7,-3,10,13,9,5,13,-4,-12,-9,13,-5,-14,3,-7,6,-12,7,10,10,12,12,9,10,-2,-9,2,-5,-8,14,0,-8,-4,-13,12,12,7,11,-15,2,-13,5,12,10,-14,13,1,-11,-3,-12,14,-6,-15,8,11,-10,7,-10,-7,14,11,8,14,14,10,11,11,-6]

想到笨拙的解法会超时,这么点数据就超时了。现在我的电脑25ms

用了index()在右侧查找第三个数c,本地时间缩短到8ms:

third submission
class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums=sorted(nums);

        rList=[]
        ai=0
        bi=ai+1
        ci=ai+2

        ll=len(nums)

        while bi<ll-1: 
            c=0-nums[ai]-nums[bi]
            
            try:
                # find c
                nums[bi+1:].index(c)
                #print('ok')
                oneList=sorted([nums[ai],nums[bi],c])
                if oneList not in rList:
                    rList.append(oneList)
            except:
                #print('error')
                pass

            bi+=1

            if bi==ll-1:
                # end is move a  
                ai+=1
                bi=ai+1
                
        return rList

Time Limit Exceeded:
命名为测试点3

Last executed input:
[82597,-9243,62390,83030,...,-97960,-23904,78409,-7418,77916]

1分钟!!摔。有很多数据可以跳过,比如俩负数,下一个肯定得找正的,做了无用功。但我还没想到一个合适的办法。

测试点2,缩小到了 3ms

class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums=sorted(nums);
        #print(nums)
        rList=[]
        ai=0

        ll=len(nums)

        nextc=ll
        prevB=0

        while ai<ll:
            bi=ai+1
            if nums[ai]>0:
                break
            while bi<nextc:
                c=0-nums[ai]-nums[bi]
                
                # 负数已完
                if c<0 or nums[ai]>0:
                    break

                if c in nums[bi+1:nextc]:
                    # find c
                    oneList=sorted([nums[ai],nums[bi],c])
                    if oneList not in rList:
                        rList.append(oneList)
                        nextc=nums.index(c)

                    #print(nums[bi+1:nextc],nextc)
                bi+=1
            ai+=1
            nextc=ll
                
        return rList

还是太臃肿了,而且最后一个超时节点也过不去。甚至本地都没出来啊。换个类似双指针的思路。

class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums=sorted(nums);
        #print(nums)
        rList=[]
        
        ll=len(nums)
        start=0
        middle=start+1
        end=ll-1

        while middle<end:
            if nums[start]>0:
                break

            #print(start,middle,end,[nums[start],nums[middle],nums[end]],0-nums[end]-nums[start]==nums[middle])
            if nums[end]+nums[start]<-nums[middle]:
                middle+=1
                
            elif nums[start]+nums[middle]>-nums[end]:
                end-=1

            else:
                oneList=sorted([nums[start],nums[middle],nums[end]])
                if oneList not in rList:
                    rList.append(oneList)
                middle+=1
                end-=1

            if middle>=end:
                start+=1
                middle=start+1
                end=ll-1
        return rList

测试点2 2.5ms (对比之前3ms应该算是差不多没有改进),测试点3终于出来了: 4.7s,还是很长,不敢去测,再想着笨拙的优化一下?提交一下吧,弄不出来了。

依旧超时

看讨论区一个O(N*N)的python解法:

by https://leetcode.com/problems/3sum/discuss/7392/Python-easy-to-understand-solution-(O(n*n)-time).

def threeSum(self, nums):
    res = []
    nums.sort()
    for i in xrange(len(nums)-2):
        if i > 0 and nums[i] == nums[i-1]:
            continue
        l, r = i+1, len(nums)-1
        while l < r:
            s = nums[i] + nums[l] + nums[r]
            if s < 0:
                l +=1 
            elif s > 0:
                r -= 1
            else:
                res.append((nums[i], nums[l], nums[r]))
                while l < r and nums[l] == nums[l+1]:
                    l += 1
                while l < r and nums[r] == nums[r-1]:
                    r -= 1
                l += 1; r -= 1
    return res

和我的想法差不多,代码都好像啊,试着分析一下为啥我的通不过。只改我认为不同的地方:现在时间4.7-4.8s

  • sorted()和list.sort()。
    • 暂时不分析排序的不同性能,替换一下也几乎没影响。
  • 首先跳过了相等的数字
    • 我也添加一个,时间5.2s竟然增加了0.4s耗时
  • 将三个值算出来和0做对比
    • 这里是应该优化,虽然感觉不重要 spend time: 4.3710356s 少了0.4s
  • while排除重复的l r 对于我没有作用,不用管
  • 添加方式不管才是我为啥费时的原因,他用的元祖不用判断重复,并且append快速。我换了元组之后时间是spend time: 1.836852s. 原来可以用元组的,最后测试发现网站自己会转为列表
maybe seventh submission
class Solution:
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums=sorted(nums)
        rList=[]
        
        ll=len(nums)
        start=0
        middle=start+1
        end=ll-1

        while middle<end:
            if nums[start]>0:
                break
            #+ spend time + 0.4s
            if start>0 and nums[start] == nums[start-1]:
                start+=1
                continue

            #print(start,middle,end,[nums[start],nums[middle],nums[end]],0-nums[end]-nums[start]==nums[middle])
            s=nums[start]+nums[middle]+nums[end]
            if s<0:
                middle+=1
                
            elif s>0:
                end-=1

            else:
                rList.append((nums[start],nums[middle],nums[end]))
                middle+=1
                end-=1

            if middle>=end:
                start+=1
                middle=start+1
                end=ll-1
        return rList

Runtime Error

Runtime Error Message:
Line 16: IndexError: list index out of range
Last executed input:
[0,0,0,0]

再改一下,spend time: 0.3842164

Wrong Answer

 
Input:
[-2,0,0,2,2]
Output:
[[-2,0,2],[-2,0,2]]
Expected:
[[-2,0,2]]

好吧,外层改成for用start遍历,现在的状态和那个解法就差不离了,提交那个吧 ><

猜你喜欢

转载自www.cnblogs.com/warcraft/p/9401019.html