[英]Why is this Python dict comprehension taking forever to run?
函數pair_exists()
將兩項作為輸入:
nums
: 一個列表(或其他數據結構)target
:一個整數如果nums
任意兩個數字總和為目標,則該函數應返回True
。 我讓它運行的列表是 1 到 100 萬個條目中的 10,000 個條目。 運行需要 20 多分鍾(雖然我有一台 MacBook Air,所以它不是最高功率的),所以我假設它壞了和/或在計算上浪費了。 我如何讓它運行?
import itertools
random.seed(a=13, version=2)
random_numbers = random.sample(range(1, 1000000), 10000)
def pair_exists(nums: list, target: int):
result = [seq for i in range(len(nums), 0, -1) for seq in itertools.combinations(nums, i) if sum(seq) == target]
print(pair_exists(random_numbers, 38109)) # SHOULD RETURN TRUE
print(pair_exists(random_numbers, 13538)) # SHOULD RETURN FALSE
不清楚為什么要檢查任何大小的子集。 你的問題陳述說你只對成對感興趣。
按照您的方法風格,我們可以在O(n^2)
編寫一個解決方案:
def pair_exists(nums, target):
return any(sum(subset) == target for subset in itertools.combinations(nums, 2))
但這在大型陣列上仍然很慢。 相反,我們可以嘗試使用兩個迭代器,它們將在O(n)
執行O(n)
由於排序,我猜在O(n*log(n))
中)。
def pair_exists(nums, target):
nums = sorted(nums)
start = 0
end = len(nums) - 1
while start < end:
if nums[start] + nums[end] < target:
start += 1
elif nums[start] + nums[end] > target:
end -= 1
else:
return True
return False
這是 O(lots) 並且不按照名稱中所說的去做; 它查找具有正確總和的任何大小的子集:
def pair_exists(nums: list, target: int):
result = [seq for i in range(len(nums), 0, -1) for seq in itertools.combinations(nums, i) if sum(seq) == target]
(此外,它不返回任何內容。)
這是 O(n²),你原來的但改編為正確的:
def pair_exists(nums: list, target: int):
return any(sum(pair) == target for pair in itertools.combinations(nums, 2))
@Bill Lynch 發布了一個 O(n log n) 的排序答案。
這是一個 O(n) 解決方案,通過確定什么會與每個值形成正確的對,並檢查它是否更早出現:
from typing import Iterable
def pair_exists(nums: Iterable[int], target: int):
seen = set()
for num in nums:
if (target - num) in seen:
return True
seen.add(num)
return False
該集合是一個具有 O(1) 插入和成員資格測試的集合,允許“較早出現”檢查很快。
此功能效率不高且與您使用的機器無關。
嘗試類似的方法來檢查您是否有對目標求和的對
def pair_exists(nums: list, target: int):
for num in nums:
if target - num in nums:
return True
return False
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.