2012-09-23 53 views
4

給定一個數字,我必須找出給定數組中所有可能的索引對,其總和等於該數。我目前正在使用以下算法:更好的算法(比使用字典)枚舉具有給定總和的對。

def myfunc(array,num): 
    dic = {} 
    for x in xrange(len(array)): # if 6 is the current key, 
     if dic.has_key(num-array[x]): #look at whether num-x is there in dic 
      for y in dic[num-array[x]]: #if yes, print all key-pair values 
       print (x,y), 
     if dic.has_key(array[x]): #check whether the current keyed value exists 
      dic[array[x]].append(x) #if so, append the index to the list of indexes for that keyed value 
     else: 
      dic[array[x]] = [x] #else create a new array 

這會在O(N)時間內運行嗎?如果不是,那麼應該怎麼做才能做到這一點?在任何情況下,它都可以在不使用任何輔助數據結構的情況下在O(N)時間內運行?

+6

你是什麼意思的話題?當你要求提供解決方案而不提供代碼時,你因不顯示研究而受到處罰。當你這樣做時,你說它應該被遷移? – SexyBeast

+2

@vascowhite(和其他密切的選民):你認爲哪個部分的FAQ「違反」?從常見問題解答:「你應該只根據你面臨的實際問題提出實際的,可回答的問題。他正在給出一個問題和他的嘗試。他還要求一個特定範圍的問題(什麼是複雜性?可以做得更好,然後O(n)?) – amit

+0

糾正我,如果我沒有得到你的問題,但如果你想找到所有對的總和等於一個給定的數字比那些對個別都要少於這個數字。所以,假設你給了一個列表'[1,2,3,4,5,6,7,8,9,10]',你必須找到所有具有'sum == 6'的對首先將列表過濾掉到[1,2,3,4,5,6],然後找到那些對。 – RanRag

回答

6

這會運行在O(N)時間嗎?

是和否。其實複雜度實際上是O(N + M),其中M輸出尺寸
不幸的是,輸出大小最壞的情況是O(N^2),例如數組[3,3,3,3,3,...,3]number == 6 - 它將導致需要生成的元素的二次數。

但是 - 漸近地說 - 它不能做得更好,因爲它在輸入大小和輸出大小上是線性的。

+0

您能否詳細說明一下?我不完全清楚。在http://www.ardendertat.com/2011/09/17/programming-interview-questions-1-array-pair-sum/上有類似的解決方案,你認爲它會表現更好嗎? – SexyBeast

+0

@Cupidvogel:我不認爲鏈接的解決方案是正確的 - 因爲它不處理重複的元素 - 這似乎是你想要的東西。鏈接的解決方案在'O(nlogn)'時間和'O(1)'空間運行 - 但是如上所述,不會打印所有重複的元素。 – amit

+0

鏈接解決方案如何在'O(log N)'時間內工作? – SexyBeast

3

非常非常簡單的解決方案,實際上通過使用數組引用在O(N)時間內運行。如果你想枚舉所有輸出對,那麼當然(作爲阿米特筆記),在最壞的情況下它必須佔用O(N^2)。

from collections import defaultdict 
def findpairs(arr, target): 
    flip = defaultdict(list) 
    for i, j in enumerate(arr): 
     flip[j].append(i) 
    for i, j in enumerate(arr): 
     if target-j in flip: 
      yield i, flip[target-j] 

後處理得到所有的輸出值(和濾除(i,i)答案):

def allpairs(arr, target): 
    for i, js in findpairs(arr, target): 
     for j in js: 
      if i < j: yield (i, j) 
+0

但是,這個解決方案是Python特有的。我正在考慮更便攜的解決方案。 – SexyBeast

+0

它不是Python特定的。你可以用任何其他語言來實現它,使用哈希表的鏈表(哈希表O(1)查找,鏈表,以便你可以引用所需的索引頭)。 – nneonneo

+0

offtop:允許'arr'是一個任意可迭代的:'用於j翻轉:如果翻譯中的目標-j:yield flip [j],翻轉[target-j]'它產生具有相應'i'的列表'j'列表(將在'allpairs()'中解壓縮) – jfs