2017-04-14 45 views
2

該文件包含100萬個正整數和負整數(可能有一些重複!)。這是整數的數組,其中第i行指定數組的第i個條目。2sum性能改進

任務是計算區間[-10000,10000](含)內的目標值數t,使輸入文件中有不同數x,y滿足x + y = t。

數字的答案是0-2的整數20001.

#ans = 427 
data, count, n = set(map(int, open('2sum.txt').read().splitlines())), 0, 1000003 

def two_sum(): 
    global count 

    H = [] 
    for i in range(n): 
     H.append(set()) 

    for x in data: 
     insert(H, x) 

    for t in range(-10000, 10000 + 1): 
     for x in data: 
      if t - x != x and lookup(H, t - x): 
       count += 1 

    print(count) 

def insert(H, x): 
    H[hashfunc(x)].add(x) 

def lookup(H, x): 
    if x in H[hashfunc(x)]: 
     return True 
    return False 

def hashfunc(x): 
    return (x >> 10) % n 

if __name__ == '__main__': 
    two_sum() 

以上代碼之間

是WAYY太慢。

編輯:我編輯代碼按照Willem Van Onsem的說法使用類似[set()] * n的語法初始化H,這是錯誤的。代碼仍然很慢,但我現在知道更多現在哈哈。

+2

但你的'[set()] * n'確實不*創建* n *個不同的集合:它會生成一個包含對同一集合的引用的列表。 –

+0

@WillemVanOnsem omg我剛剛測試過,你是對的!我不知道。這是爲什麼發生?我通常初始化像[None] * n這樣的列表,所以我天真地認爲[set()] * n也可以工作! –

+0

你不能擺脫查找功能嗎?你只需要t -x數據。那麼你也不需要H。 – Elan

回答

0

我不能運行你的代碼,但我建議你使用配置文件來判斷性能。 我認爲所有的問題發生在

for t in range(-10000, 10000 + 1): 
    for x in data: 
     if t - x != x and lookup(H, t - x): 
      count += 1 

這是一個O(N * N)的操作。

也許你應該嘗試hashtable解決方案。

+0

這**實際上是** hashtable解決方案。如你所說,這個雙重for循環實際上並不是「O(n^2)」。因爲這裏的n等於1百萬,而不是20002。因此,雙for循環更像是'20002 * n',這又是'O(n)'。但是我會同意,在這個運行時中,常量20002真的非常糟糕。這實際上是我要求的修復。 –

+0

然後您可以嘗試將百萬轉化爲20002,並記錄時間,使用[PROFILE](https://docs.python.org/2/library/profile.html)@PranjalVerma – obgnaw