簡體   English   中英

具有兩個調用的遞歸函數的時間復雜度

[英]Time complexity of a recursive function with two calls

考慮以下代碼:

def count_7(lst):
    if len(lst) == 1:
        if lst[0] == 7:
            return 1
        else:
            return 0

    return count_7(lst[:len(lst)//2]) + count_7(lst[len(lst)//2:])

注意:切片操作將被視為O(1)。

所以,我的語言告訴我它是O(n * logn),但我正在努力證明它是科學的。
很高興幫忙!

好的,數學上(有點像)我得到這樣的東西:

T(n) = 2T(n/2) + c
T(1) = 1

推廣等式:

T(n) = 2^k * T(n/2^k) + (2^k - 1) * c
T(1) = 1

k == logNn/2^k == 1所以:

T(n) = 2^logN * T(1) + (2^logN - 1) * c

因為T(1) = 1並且應用對數性質

T(n) = n * 1 + (n-1) * c
T(n) = n + n * c
T(n) = n * (1+c)
T(n) = O(n)

這不是O(n*logn)的線索是您不必將兩個子問題組合在一起。 mergesort不同,您必須組合兩個子數組,此算法不必對遞歸結果執行任何操作,因此其時間可以表示為常量c

更新:直覺背后

此算法應為O(n),因為您只訪問數組中的每個元素一次 它可能看起來並不簡單,因為遞歸永遠不會。

例如,你將問題分成兩個子問題的一半大小,然后將每個子問題分成一半大小並繼續進行,直到每個子問題的大小為1. 當你完成時,你將有n個子問題,大小為1 , n*O(1) = O(n)

從第一個問題開始到大小為1的N個問題的路徑是對數的,因為在每個步驟中,您將細分為兩個。 但是在每個步驟中,您都不會對結果做任何事情,因此這不會給解決方案增加任何時間復雜性。

希望這可以幫助

最簡單的方法是假設n是2的倍數以簡化: n = 2 m

算法的時間復雜度是(c是常數):

t(n) = 2 t(n/2) + c

使用遞歸你會得到:

t(n) = 2 2 t(n/2 2 ) + 2c + c

...

= 2 log(n) t(n/2 log(n) ) + c(2 log(n)-1 + ... + 2 2 + 2 1 + 2 0 )

通過注意log(n) = m可以簡化,因此2 log(n) = 2 m = n

= n + c(2 log(n)-1 + ... + 2 2 + 2 1 + 2 0 )

最后,上面的總和可以減少到2 log(n) (等於n

 t(n) = (1 + c) n

所以你的解決方案是O(n)

您掃描列表的所有元素一次,即O(n)。 與簡單遞歸掃描的唯一區別在於掃描它們的順序。 你做1,n / 2,2,3 / 4n等......而不是1,2,3 ....但復雜性是相同的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM