當 n = 1 時,f(n) = 1;
當 n > 1 時,f(n) = 2*f(n/2) + n ;
求f(n)的遞歸式
首先為什么要求遞歸式呢? 是因為在計算機中有些算法是使用遞歸方式實現,我們需要計算該遞歸方式的時間復雜度,來評定算法的優劣。
下面我們來求f(n)的遞歸式,什么是遞歸式呢?就是等號左邊只有f(n),等號右邊只有關於n的表達式。
看到f(n) = 2*f(n/2) + n 這個式子你想到了什么,是不是將f(n/2)變掉。
如何將f(n/2) 變掉呢?
可以假設 n = 2k ,那么 f(n) = f(2k) 然后假設 f(2k) = h(k), f(n/2) = f(k) = h(k/2) 顯然這么做毫無意義。
也可以假設 n = 2^k ,那么 f(n) = f(2^k) 然后假設 f(2^k) = h(k), f(n/2) = f(2^(k-1)) = h(k-1)。
那么 f(n) = 2*f(n/2) + n => h(k) = 2*h(k-1) + 2^k ;
另外 n = 1 時,f(n) = 1 ,1 = 2^k => k = 0 時 h(k) = 1 ;
換句話說就是
將
當 n = 1 時,f(n) = 1;
當 n > 1 時,f(n) = 2*f(n/2) + n ;
=>
n = 2^k ;
當 k = 0 時 h(k) = 1 ;
當 k > 0 時 h(k) = 2*h(k-1) + 2^k ;
h(1) = 2*h(0) + 2^1
h(2) = 2*h(1) + 2^2
h(3) = 2*h(2) + 2^3
h(3)= 2*(2*h(1) + 2^2) + 2^3
= 2^2 * h(1) + 2^3 + 2^3
= 2^2 * (2*h(0) + 2^1) + 2^3 + 2^3
= 2^3 * h(0) + 2^3 + 2^3 + 2^3
= 4 * 2^3
h(k) = 2^k * h(0) + k * (2^k)
= (k + 1) * 2^k
我們得到了 h(k) = (k + 1) * 2^k ,因為 n = 2^k => k = log2 n , f(n) = h(k)
f(n) = (log2 n + 1) * 2^log2 n
= (log2 n + 1) * n
= n * log2 n + n
於是得到了 f(n) = n * log2 n + n 。
在得到了遞歸式之后,時間復雜度 O(nlog2 n)
延伸知識:
求等差數列的前n項和,求等比數列的前n項和
等差數列 A1 = 1,A2 = 2, A3 = 3 …… An = n ; 等差數列 每一項都是前一項加一個常數,這里是1
Sn = A1 + A2 + A3 + …… + An
= 1 + 2 + 3 + …… + n
以下是等差數列的前n項和的推導過程
Sn = 1 + 2 + 3 + …… + n
Sn = n + (n - 1) + (n - 2) + …… + 1
Sn + Sn = (1 + n) + (2 + (n - 1)) + (3 + (n - 2)) + …… + (1 + n)
2 * Sn = n * (n + 1)
Sn = n * (n + 1)/2
等比數列 A1 = 2^1,A2 = 2^2, A3 = 2^3 …… An = 2^n ; 等比數列 每一項都是前一項乘以個常數,這里是2
Sn = A1 + A2 + A3 + …… + An
= 2^1 + 2^2 + 2^3 + …… + 2^n
Sn = 2^1 + 2^2 + 2^3 + …… + 2^n
2 * Sn = 2^2 + 2^3 + …… + 2^n + 2^(n + 1)
2 * Sn - Sn = 2^(n + 1) - 2^1
Sn = (2^(n + 1) - 2^1 ) / (2 - 1)