簡體   English   中英

遞歸解決方案的Big-O復雜性

[英]Big-O complexity of a recursive solution

我有一個簡單的遞歸解決方案,如下所示:

public int countPaths(int x, int y) {

    if(x == 0 && y == 0) {
        return 0;
    } else if(x == 0) {
        return 1;
    } else if(y == 0) {
        return 1;
    } else {
        int count = countPaths(x-1, y);
        count += countPaths(x, y-1);
        return count;
    }
}

這是為了解決書中的以下問題: 破解編碼面試

想象一個機器人坐在X by Y網格的左上角。 機器人只能在兩個方向上移動:向右和向下。 機器人從(0,0)到(X,Y)有多少種可能的路徑?

我試圖確定運行時的復雜度,我相信它是O(x + y)。 我通過使用遞歸樹來實現這一點,例如,如果x = 2和y = 2 在此處輸入圖片說明

該樹的最大深度為(x + y),並且在每個步驟中完成的工作都是一個常數。 因此,完成的最大工作量為(x + y)* c,因此運行時復雜度為O(x + y)

問題1:我正確嗎? 我相信我計算出的上限不夠嚴格

問題2:接下來,如果我要使用備忘錄來改善運行時間,從而不重復計算子問題,那么Big-o所述的運行時復雜度將如何改變?

雖然樹的深度確實是O(x + y),但每一層上的節點越來越多,而節點的數量決定了復雜性,而不是樹的深度。

如果寫下運行時的重復關系,則會得到:

T(0, y) = T(x, 0) = 1
T(x, y) = T(x-1, y) + T(x, y-1) + 1

如果忽略第二個方程式的+1(只能使運行時更好),則會得到與代碼最初計算的函數相同的函數,即select(x + y,y)。

對於x = y,這是中心二項式系數,大約為4 ^ x / sqrt(pi * x),即使x的值適中,其值也足以使算法無效。

使用備忘錄,您需要為x和y的每個值進行恆定量的工作,因此復雜度為O(xy)。

如果您根據評估給定對(x, y)的計數所需的加法數來評估復雜性,則會得到遞歸

A(x,y) = A(x-1,y) + A(x,y-1) + 1

其中A(x,0) = A(0,y) = 0

設置A(x,y) = P(x,y) - 1遞歸變為

P(x,y) - 1 = P(x-1,y) - 1 + P(x,y-1) - 1 + 1,

要么

P(x,y) = P(x-1,y) + P(x,y-1),

P(x,0) = P(0,y) = 1 ,它給出了經典的Pascal三角形,並且

A(x,y) = (x+y)!/(x!y!) - 1.

您還可以處理許多遞歸函數調用,

C(x,y) = C(x-1,y) + C(x,y-1) + 2,

其中C(0,y) = C(x,0) = 0

您將通過設置C(x,y) = 2P(x,y) - 2來解決它,並獲得

C(x,y)= 2(x+y)!/(x!y!)-2.

關於漸進復雜度,這沒有區別。 沒有比O((x+y)!/x!y!)更簡單的公式了。

使用備忘錄時,每次求值( x, y>0 )僅花費一次加法或兩次調用,並且假設存儲/檢索值的時間恆定,則總復雜度要好得多O(xy)

根據@Anonymous的寶貴輸入,我們知道重復關系為:

T(x, y) = T(x-1, y) + T(x, y-1) + 1
Abusing (which is ok in Big-O analysis) the notation, let x = y 
T(x, x) = 2 * T(x-1, x) = 2 * 2 * T(x-2, x) = ... = 2 * ... * 2 * T(0, x)
        = O(2^x)

所以運行時的復雜度是

O(2 ^ n) ; 其中n = max(x,y)

有了備忘錄,我明白了,謝謝@Anonymous,它應該是O(xy)

暫無
暫無

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

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