既然你不是在問一個確切的解決方案(但是,我可以提供,如果你想),我會給你一個提示,這是一個非常簡單,但不是一個衆所周知的接近方法這樣的問題。
的關鍵思路是修改功能,其中有可能是最糟糕的複雜的功能,但其預期複雜性很容易被衡量,我們稱之爲修正功能findTarget2
:
public static int findTarget2 (int[] a, int low, int high, int goal) {
if (low == high) return 0;
int len = high - low + 1; //length of the array range, i.e. input size
while (true) {
int target = selectTarget(a, low, high);
if (goal < target && target-low <= 3/4 * len)
return findTarget2(a, low, target-1, goal);
else if (goal > target && high-target <= 3/4 * len)
return findTarget2(a, target+1, high, goal);
else if (goal == target)
return a[target];
}
}
現在,讓我們f(n)
是原始的時間複雜度,並且g(n)
是findTarget2
函數的時間複雜度,其中n
是它們輸入的大小,即數組範圍的長度等於high-low+1
。
現在,讓我們說,selectTarget
導致錯誤的執行當且僅當它不會引起,而體內的任何回覆呼叫。
第一觀察是g(n) >= f(n)
,因爲在錯誤的執行的情況下,基本上findTarget2
調用自身上相同的輸入,而原來的功能降低了輸入的由至少1的尺寸。因此,如果有一個上限對於g(n)
,則相同的限制適用於f(n)
。
接着,g(n)
預期時間複雜性可被寫爲如下:
EX[g(n)] <= EX[g(3/4 * n) + X * O(n)]
其可以被寫爲如下使用線性期望值:
EX[g(n)] <= EX[g(3/4 * n)] + EX[X] * O(n)
其中X
是隨機變量表示while循環執行的次數,直到它返回調用,最後的O(n)
是在findTarget2
函數中花費的非遞歸時間,它是O(n)
,因爲據說selectTarget
函數在那個時候運行。
現在你的任務就是計算EX[X]
,然後你可以使用Master theorem獲得的g(n)
最終預期的時間複雜度,這也是一個上限的f(n)
預期的時間複雜度,因此上界的複雜性原始功能。
謝謝。一個問題:selectTarget()究竟做了什麼?它是否像指定範圍之間的隨機值? – Wazowski
@Wazowski定義了它的作用:「非遞歸方法selectTarget()具有線性時間複雜度T(n)= c·n,其中n = high - low + 1並返回低範圍內的整數目標low≤target≤high 。在這個範圍內,selectTarget()的輸出值是均勻分佈的,因此如果low = 0且high = n-1,那麼每個target = 0,1,...,n-1以相同的概率1/n出現。 「重要的是它以相同的概率返回每個值。 – pkacprzak
我知道,但我沒有得到它返回的結果,是一個範圍內的隨機整數? – Wazowski