Python 3Sum-时间复杂度

Python 3Sum-时间复杂度,python,arrays,Python,Arrays,给定一个由n个整数组成的数组nums,nums中是否有元素a、b、c使得a+b+c=0?查找数组中所有唯一的三元组,该数组的和为零 注: 解决方案集不得包含重复的三元组 例如: Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ] 这是我的密码: class Solution: def threeSum(self, nums: List[int]) -&

给定一个由n个整数组成的数组nums,nums中是否有元素a、b、c使得a+b+c=0?查找数组中所有唯一的三元组,该数组的和为零

注:

解决方案集不得包含重复的三元组

例如:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
这是我的密码:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        firstPointer = 0
        if len(nums) ==0:
            return []
        sum = 0
        sum = nums[0]
        numDict = {}
        result = []

        for i in nums:
            numDict[i] = numDict.get(i,0)+1 //Adding to Dict

        while firstPointer<len(nums):
            sum = nums[firstPointer]
            for index, value in enumerate(nums):
                if -(sum+value) in numDict and index!=firstPointer and index!=nums.index(-sum-value) and firstPointer!=nums.index(-sum-value):
                        add = [sum,nums[index],-(sum+value)] //Removing Duplicates
                        add.sort()
                        if add not in result:
                            result.append(add)

            firstPointer+=1


        return result
类解决方案:
def threeSum(self,nums:List[int])->List[List[int]:
firstPointer=0
如果len(nums)==0:
返回[]
总和=0
总和=nums[0]
numDict={}
结果=[]
对于nums中的i:
numDict[i]=numDict.get(i,0)+1//添加到Dict
而firstPointer可以与
np.sort
np.unique
一起使用:

from itertools import combinations


使用@lenik方法的备选方案

l = []
ordered_arr = list(sorted(array_nums))
for i,val1 in enumerate(ordered_arr):
    if val1>0:
        break
    for val2 in ordered_arr[i+1:len(array_nums)-1]:
        sum1 = val1 + val2
        if sum1>0:
            break
        for val3 in ordered_arr[i+2:len(array_nums)]:
            tup = (val1, val2, val3)
            if (sum1 +val3) ==0 :
                l.append(tup)
list(set([tuple(sorted(comb)) for comb in l]))
测试

import numpy as np
np.random.seed(0)
array_nums = np.random.randint(-100 , 100, 400).tolist()

时间:


时间:


时间:


对于一个更简单的问题,如
a+b=0
的解决方案对于预排序数组需要一个线性的O(N)时间,如果需要先对其排序,则需要O(NlogN)时间。下面是一个计划,您将数组按O(NlogN)排序,然后执行以下操作:

  • 取第一个元素,命名为“C”,在线性时间内求解
    a+b=-C
  • 取另一个元素,将其命名为“C”
  • 继续,直到数组中的所有元素都用完为止

  • 总的来说,这将给你O(N^2)复杂度。

    你认为
    nums.index
    需要多长时间?它返回第一个检出的元素的索引,所以我猜是O(N)top?嗯,我明白你的意思了。那么这里的复杂性是n^4@user2357112supportsMonica提供了三种方法的描述和代码,其中两种是O(n^2)。@DarrylG我知道这一点。我想知道我的代码花费了多少时间,以及为什么这会如此惊人。但地图在这里的意义是什么?如果它是一个列表,为什么.tolist()在那之后?请纠正我,但是
    组合(…,3)
    的复杂性是O(N^3)?映射到这里,对数组的每个元素应用一个函数并返回一个迭代器,
    tolist
    ,以便将
    np.array
    转换为列表
    l = []
    ordered_arr = list(sorted(array_nums))
    for i,val1 in enumerate(ordered_arr):
        if val1>0:
            break
        for val2 in ordered_arr[i+1:len(array_nums)-1]:
            sum1 = val1 + val2
            if sum1>0:
                break
            for val3 in ordered_arr[i+2:len(array_nums)]:
                tup = (val1, val2, val3)
                if (sum1 +val3) ==0 :
                    l.append(tup)
    list(set([tuple(sorted(comb)) for comb in l]))
    
    import numpy as np
    np.random.seed(0)
    array_nums = np.random.randint(-100 , 100, 400).tolist()
    
    %%timeit
    np.unique(list(map(np.sort,filter(lambda x: sum(x)==0,
                                       combinations(array_nums,3)))),
              axis=0).tolist()
    
    2.93 s ± 136 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    %%timeit
    list(set([tuple(sorted(comb)) 
              for comb in filter(lambda x: sum(x)==0,
                                 combinations(array_nums,3))]))
    
    2.66 s ± 66.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    %%timeit
    l = []
    ordered_arr = list(sorted(array_nums))
    for i,val1 in enumerate(ordered_arr):
        if val1>0:
            break
        for val2 in ordered_arr[i+1:len(array_nums)-1]:
            sum1 = val1 + val2
            if sum1>0:
                break
            for val3 in ordered_arr[i+2:len(array_nums)]:
                tup = (val1, val2, val3)
                if (sum1 +val3) ==0 :
                    l.append(tup)
    list(set([tuple(sorted(comb)) for comb in l]))
    
    1.34 s ± 87.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)