簡體   English   中英

3Sum - 時間復雜度

[英]3Sum - Time Complexity

給定一個由 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

這段代碼在 leetcode 上通過了 311/313 個測試用例。 然而,對於一個非常長的輸入數組,它給出了一個時間限制超過錯誤。 但是這個問題的最佳解決方案是 O(n^2) 復雜度,而我的解決方案幾乎是 O(n^2) 對嗎?

您可以combinations使用np.sortnp.unique

from itertools import combinations

list(set([tuple(sorted(comb)) 
          for comb in filter(lambda x: sum(x)==0,
                             combinations(array_nums,3))]))
#[(-1, -1, 2), (-1, 0, 1)]

list(map(list,set([tuple(sorted(comb)) 
                    for comb in filter(lambda x: sum(x)==0,
                                        combinations(array_nums,3))])))
#[[-1, -1, 2], [-1, 0, 1]]

使用@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()

%%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)

一個更簡單的問題的解決方案,比如a+b = 0需要一個線性 O(N) 時間與一個預先排序的數組或 O(NlogN) 如果你需要先排序它。 所以這是一個計划,你在 O(NlogN) 中對你的數組進行排序,然后執行以下操作:

  1. 取第一個元素,將其命名為“C”,在線性時間內求解a+b = -C
  2. 取另一個元素,將其命名為“C”....
  3. 繼續直到數組中的所有元素都用完。

總的來說,這會給你 O(N^2) 的復雜度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM