2016-09-19 57 views
0
def firstMissingPositive(self, A): 
    least = 1024*1024*1024 
    # worst case n ops 
    for i in A: 
     if i < least and i > 0: 
      least = i 
    if least > 1: 
     return 1 
    else: 
     # should be O(n) 
     A_set = set(A) 
     # worst case n ops again 
     while True: 
      least += 1 
      if least not in A_set: 
       return least 

我只問,因爲它對於給定的問題似乎太簡單了,這裏的大多數人可能在Leetcode或類似的地方看過。在Python的set或dict的實現中有沒有我不知道的東西?查找應該是O(1),根據我的理解,將列表轉換爲集合應該是O(n)。下面的函數是O(n)時間和O(1)空間,其中n = | A |?

+6

顯然不是O(1)空間。 –

+0

是否可以將數組更改爲哈希映射來克服該部分?我認爲那是有的,並沒有太注意它。 – szhongren

+0

也許在理論上,但你的代碼沒有這樣做,它可能不會有用,因爲你會處理的加載因子爲1. – user2357112

回答

2

這不是O(1)空間,它是O(n)空間,因爲你需要構建集合。

至於時間,根據the Python wiki,設置遏制需要O(n)最壞的情況。所以你的算法是O(n^2)。請注意,這是最糟糕的情況 - 設置遏制的平均時間爲O(1),因此算法的平均時間複雜度確實爲O(n)

通過使用有序集,您可以將最差情況降至O(n log n),但平均時間也將爲O(n log n)

+2

作爲O(n)不排除是O (1)和O(n^2)不排除是O(n)。設置遏制通常被認爲是O(1),至少在LeetCode(這是從哪裏來),所以它會在那裏計爲O(n)時間。我認爲你的意思是「平均」,而不是「攤銷」。 –

+0

啊,這是有道理的,但如何設置遏制O(n)的最壞情況?它不僅僅是一個哈希函數,它將一個索引寫入一個數組,然後你可以檢查它是否已經被初始化了? – szhongren

+0

@szhongren它確實是一個散列函數。但是散列函數並不完美,不同的對象可以具有相同的散列(稱爲散列衝突,並且有處理它的技術)。因此,在最壞的情況下,你可以有'n'散列衝突(你所有的密鑰都有相同的散列),你必須循環它們才能找到合適的散列。但是,這可能永遠不會發生,這就是爲什麼它的平均成本是「O(1)」。 –

相關問題