【算法分析与设计】HW1
Question
使用生成函数法分析斐波拉契数列的时间复杂度。
斐波拉契数列:
f ( n ) = { 1 n = 1 , 2 f ( n − 1 ) + f ( n − 2 ) n > 2 f(n)=\begin{cases} 1 & n=1,2 \\ f(n-1)+f(n-2) & n>2 \end{cases} f(n)={1f(n−1)+f(n−2)n=1,2n>2
reference
生成函数法步骤:
-
把递归函数 h ( n ) h(n) h(n) 的各个取值构造函数 G ( x ) G(x) G(x) :
G ( x ) = h ( 1 ) x + h ( 2 ) x 2 + h ( 3 ) x 3 + ⋯ = ∑ k = 1 ∞ h ( k ) x k G(x)=h(1)x+h(2)x^2+h(3)x^3+\dots=\sum_{k=1}^\infin h(k)x^k G(x)=h(1)x+h(2)x2+h(3)x3+⋯=∑k=1∞h(k)xk
-
为了求出 h ( n ) h(n) h(n) ,对 G ( x ) G(x) G(x) 进行演算,求出其解析表达式
-
再对 G ( x ) G(x) G(x) 的解析表达式转换为对应的幂级数
-
对照幂级数的系数,获得 h ( n ) h(n) h(n) 的解析表达式
Answer
-
构造生成函数 G ( x ) G(x) G(x) :
G ( x ) = f ( 1 ) x + f ( 2 ) x 2 + f ( 3 ) x 3 + ⋯ = ∑ k = 1 ∞ f ( k ) x k G(x)=f(1)x+f(2)x^2+f(3)x^3+\dots=\sum_{k=1}^\infin f(k)x^k G(x)=f(1)x+f(2)x2+f(3)x3+⋯=k=1∑∞f(k)xk
-
演算:
观察递推公式 f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n)=f(n-1)+f(n-2) f(n)=f(n−1)+f(n−2) ,该公式是关于连续三项的关系,且系数均为常数1,所以可以进行如下变化:
G ( x ) = f ( 1 ) x + f ( 2 ) x 2 + f ( 3 ) x 3 + f ( 4 ) x 4 + f ( 5 ) x 5 + … x G ( x ) = f ( 1 ) x 2 + f ( 2 ) x 3 + f ( 3 ) x 4 + f ( 4 ) x 5 + … x 2 G ( x ) = f ( 1 ) x 3 + f ( 2 ) x 4 + f ( 3 ) x 5 + … \begin{aligned} G(x)=f(1)x+f(2)x^2+f(3)x^3+f(4)x^4+f(5)x^5+\dots \\ xG(x)=f(1)x^2+f(2)x^3+f(3)x^4+f(4)x^5+\dots \\ x^2G(x)=f(1)x^3+f(2)x^4+f(3)x^5+\dots \end{aligned} G(x)=f(1)x+f(2)x2+f(3)x3+f(4)x4+f(5)x5+…xG(x)=f(1)x2+f(2)x3+f(3)x4+f(4)x5+…x2G(x)=f(1)x3+f(2)x4+f(3)x5+…
根据斐波拉契数列可知,
{ f ( 1 ) = 1 f ( 2 ) − f ( 1 ) = 0 f ( n ) − f ( n − 1 ) − f ( n − 2 ) = 0 ( n > 2 ) \begin{cases} f(1)=1 \\ f(2)-f(1)=0 \\ f(n)-f(n-1)-f(n-2)=0 & (n>2) \end{cases} ⎩⎪⎨⎪⎧f(1)=1f(2)−f(1)=0f(n)−f(n−1)−f(n−2)=0(n>2)
( 1 − x − x 2 ) G ( x ) = f ( 1 ) x + ( f ( 2 ) − f ( 1 ) ) x 2 + ( f ( 3 ) − f ( 2 ) − f ( 1 ) ) x 3 + ( f ( 4 ) − f ( 3 ) − f ( 2 ) ) x 4 + … = x + 0 ⋅ x 2 + 0 ⋅ x 3 + 0 ⋅ x 4 + … = x \begin{aligned} (1-x-x^2)G(x)=& f(1)x+(f(2)-f(1))x^2+(f(3)-f(2)-f(1))x^3+(f(4)-f(3)-f(2))x^4+\dots \\ =& x+0\cdot x^2+0\cdot x^3+0\cdot x^4+\dots \\ =& x \end{aligned} (1−x−x2)G(x)===f(1)x+(f(2)−f(1))x2+(f(3)−f(2)−f(1))x3+(f(4)−f(3)−f(2))x4+…x+0⋅x2+0⋅x3+0⋅x4+…x
⇒ G ( x ) = x 1 − x − x 2 \Rightarrow G(x)=\frac x{1-x-x^2} ⇒G(x)=1−x−x2x
-
将 G ( x ) = x 1 − x − x 2 G(x)=\frac x{1-x-x^2} G(x)=1−x−x2x 转化成幂级数:
G ( x ) = x 1 − x − x 2 = x ( 1 − α x ) ( 1 − β x ) G(x)=\frac x{1-x-x^2}=\frac x{(1-\alpha x)(1-\beta x)} G(x)=1−x−x2x=(1−αx)(1−βx)x,其中 α = 1 + 5 2 , β = 1 − 5 2 \alpha=\frac {1+\sqrt {5}}{2},\beta=\frac {1-\sqrt {5}}{2} α=21+5,β=21−5
G ( x ) = A 1 − α x + B 1 − β x G(x)=\frac A{1-\alpha x}+ \frac B{1-\beta x} G(x)=1−αxA+1−βxB,求得 A = 1 5 , B = − 1 5 A=\frac 1{\sqrt {5}},B=-\frac 1{\sqrt {5}} A=51,B=−51
根据公式:
1 1 − x = ∑ k = 0 ∞ x k \frac 1{1-x}=\sum_{k=0}^{\infin}x^k 1−x1=∑k=0∞xk
⇒ 1 1 − α x = ∑ k = 0 ∞ ( α x ) k \Rightarrow \frac 1{1-\alpha x}=\sum_{k=0}^{\infin}(\alpha x)^k ⇒1−αx1=∑k=0∞(αx)k
⇒ 1 1 − β x = ∑ k = 0 ∞ ( β x ) k \Rightarrow \frac 1{1-\beta x}=\sum_{k=0}^{\infin}(\beta x)^k ⇒1−βx1=∑k=0∞(βx)k
可得幂级数:
G ( x ) = A ∑ k = 0 ∞ ( α x ) k + B ∑ k = 0 ∞ ( β x ) k = ∑ k = 0 ∞ ( A ( α x ) k + B ( β x ) k ) = ∑ k = 1 ∞ ( A ( α x ) k + B ( β x ) k ) = ∑ k = 1 ∞ ( A α k + B β k ) x k = ∑ k = 1 ∞ f ( k ) x k \begin{aligned} G(x)=&A\sum_{k=0}^{\infin}(\alpha x)^k+B\sum_{k=0}^{\infin}(\beta x)^k \\ =&\sum_{k=0}^{\infin}(A(\alpha x)^k+B(\beta x)^k) \\ =&\sum_{k=1}^{\infin}(A(\alpha x)^k+B(\beta x)^k) \\ =&\sum_{k=1}^{\infin}(A\alpha ^k+B\beta^k)x^k \\ =&\sum_{k=1}^\infin f(k)x^k \end{aligned} G(x)=====Ak=0∑∞(αx)k+Bk=0∑∞(βx)kk=0∑∞(A(αx)k+B(βx)k)k=1∑∞(A(αx)k+B(βx)k)k=1∑∞(Aαk+Bβk)xkk=1∑∞f(k)xk -
对照幂级数的系数,获得 f ( n ) f(n) f(n) 的解析表达式
f ( n ) = A α n + B β n = 1 5 ( ( 1 + 5 2 ) n − ( 1 − 5 2 ) n ) \begin{aligned} f(n)=&A\alpha ^n+B\beta^n \\ =&\frac 1{\sqrt {5}}((\frac {1+\sqrt {5}}{2})^n-(\frac {1-\sqrt {5}}{2})^n) \end{aligned} f(n)==Aαn+Bβn51((21+5)n−(21−5)n)
时间复杂度分析:
利用生成函数法解得
f
(
n
)
f(n)
f(n) 的一般表达式,则斐波拉契数列的时间复杂度就是计算
1
5
(
(
1
+
5
2
)
n
−
(
1
−
5
2
)
n
)
\frac 1{\sqrt {5}}((\frac {1+\sqrt {5}}{2})^n-(\frac {1-\sqrt {5}}{2})^n)
51((21+5)n−(21−5)n) 的复杂度,编码上似乎只用一行代码就能解决,时间复杂度为
O
(
1
)
O(1)
O(1),当然你可以不调用power
函数,自己写算法计算乘方,乘方计算较高效时间复杂度为
O
(
l
o
g
n
)
O(log n)
O(logn)。