[英]Big-O of Fibonacci with memoization?
首先,算法的下限是O(n)
僅僅是因為對於給定的n
您要用n
值填充字典(假設我們正在處理對Fib
第一次調用)。
另一方面,對於每個n
您在Fib
函數中執行的每個操作均攤銷O(1)
。 因此,總的來說,您第一次致電 Fib
將攤銷O(n)
。
請注意,對於較大的n
此值可能會高於O(n)
因為not in
運行時不是O(1)
(僅攤銷O(1)
)。 n
必須是多少? 不知道,取決於底層的哈希函數。 另外,在達到n
之前,您可能會耗盡內存。
現在,這顯然是以空間(即內存)為代價的,它也變為O(n)
。 而且這僅是在每個整數都占用相同數量的空間的前提下進行的,不幸的是,對於Python而言,這是不正確的。 “不限制整數”方法的結果是,大整數作為數字數組保留在內存中。 由於數字n
最多具有log_b(n)+1
數字(其中b
是數字系統,例如10
為十進制系統,因此我不確定哪個Python內部使用),我們得出實際空間復雜度在O(n)
之間和O(log_b(n!))
如果我們不在乎是不是第一次打電話,事情就會變得更加復雜。 但是只有一點。 您通常可以輕松地檢查出Fib
是O(max(nk, 1))
復雜度,其中k
是調用時memo
字典的大小。
將其與例如迭代方法進行比較。 在這種方法中,您始終要保留2個最后一個元素和一個計數器。 這樣,您將獲得O(n)
時間復雜度和O(1)
空間復雜度。
當然,對於朴素的遞歸斐波那契,時間復雜度為O(2^n)
,空間復雜度為O(n)
(由於調用堆棧)。
我的感覺是它仍然是O(n),假設您計算Fin(100),則需要在計算100前計算所有數字。確定是否已完成前一次運行,那么您會將其存儲在內存中,但是對於您可以想象並已執行上一個執行的任何數字,我可以想象一個更大的數字:)
也許您可以說它是O(1)攤銷的(與Java中的ArrayList獲得元素的O(1)一樣……實際上是O(n),因為您可能需要調整數組的大小,但是通常情況並非如此,因此O(1)是“可接受的”量度)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.