[英]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.sort
和np.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) 中對你的數組進行排序,然后執行以下操作:
a+b = -C
。總的來說,這會給你 O(N^2) 的復雜度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.