Merge Sort问题
要求将A列表进行排序操作(假设该排序算法的复杂度为
T
(
n
)
T(n)
T(n)),那么可以将其对半分,分成子问题1(复杂度为
T
(
n
2
)
T(\frac{n}{2})
T(2n))和子问题2(复杂度为
T
(
n
2
)
T(\frac{n}{2})
T(2n)),然后将子问题1和子问题2中的元素一个一个对比,最终得到最后的排序复杂度为
O
(
n
)
O(n)
O(n),如果是分成三个子问题,复杂度为
O
(
2
n
)
O(2n)
O(2n),因为这里经过了2次对比操作。
因此分成2次的结果为
T
(
n
)
=
T
(
n
2
)
+
T
(
n
2
)
+
n
T(n)=T(\frac{n}{2})+T(\frac{n}{2})+n
T(n)=T(2n)+T(2n)+n
Master Theorem(主定理分析)
假设某个递归算法的时间复杂度递归公式为:
T
(
n
)
=
a
T
(
n
b
)
+
f
(
n
)
T(n)=aT(\frac{n}{b})+f(n)
T(n)=aT(bn)+f(n)
(此处只是作为算法复杂度的分析,数学上并不严格)
1.若
O
(
n
l
o
g
b
a
)
>
f
(
n
)
O(n^{log_{b}a})>f(n)
O(nlogba)>f(n),算法复杂度则为
O
(
n
l
o
g
b
a
)
O(n^{log_{b}a})
O(nlogba)
2.若
O
(
n
l
o
g
b
a
)
=
f
(
n
)
O(n^{log_{b}a})=f(n)
O(nlogba)=f(n),算法复杂度则为
O
(
n
l
o
g
b
a
l
o
g
n
)
O(n^{log_{b}a}log n)
O(nlogbalogn)
3.若
O
(
n
l
o
g
b
a
)
<
f
(
n
)
O(n^{log_{b}a})<f(n)
O(nlogba)<f(n),算法复杂度则为
O
(
f
(
n
)
)
O(f(n))
O(f(n))
例子1:
T
(
n
)
=
3
T
(
n
2
)
+
n
2
T(n)=3T(\frac{n}{2})+n^{2}
T(n)=3T(2n)+n2
此时
a
=
3
,
b
=
2
,
f
(
n
)
=
n
2
a=3,b=2,f(n)=n^{2}
a=3,b=2,f(n)=n2
n
l
o
g
b
a
=
n
l
o
g
2
3
=
n
1.6
<
n
2
n^{log_{b}^{a}}=n^{log_{2}3}=n^{1.6}<n^{2}
nlogba=nlog23=n1.6<n2
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^{2})
T(n)=O(n2)
例子2:
T
(
n
)
=
4
T
(
n
2
)
+
n
2
T(n)=4T(\frac{n}{2})+n^{2}
T(n)=4T(2n)+n2
此时
a
=
4
,
b
=
2
,
f
(
n
)
=
n
2
a=4,b=2,f(n)=n^{2}
a=4,b=2,f(n)=n2
n
l
o
g
b
a
=
n
l
o
g
2
4
=
n
2
=
n
2
n^{log_{b}^{a}}=n^{log_{2}4}=n^{2}=n^{2}
nlogba=nlog24=n2=n2
T
(
n
)
=
O
(
n
2
l
o
g
n
)
T(n)=O(n^{2}logn)
T(n)=O(n2logn)
Fibonanci number(斐波那契数)
序列为1,1,2,3,5,8,13,21,… 问题:怎么求出序列中第N个数,
T
(
n
)
=
T
(
n
−
2
)
+
T
(
n
−
1
)
T(n) = T(n-2) + T(n-1)
T(n)=T(n−2)+T(n−1)
1.递归求解
def fib(n):
# base case
if n < 3:
return 1
return fib(n-2)+fib(n-1)
时间复杂度为
O
(
2
n
)
O(2^{n})
O(2n)
空间复杂度:
O
(
n
)
O(n)
O(n)
2.循环求解
时间复杂度为
O
(
n
)
O(n)
O(n),空间复杂度为
O
(
n
)
O(n)
O(n)
import numpy as np
def fib(n):
tmp = np.zeros(n)
tmp[0] = 1
tmp[1] = 1
for i in range(2,n):
tmp[i] = tmp[i-2]+tmp[i-1]
return tmp[n-1]
3.循环求解
(
f
(
n
)
f
(
n
−
1
)
)
=
(
1
1
1
0
)
(
f
(
n
−
1
)
f
(
n
−
2
)
)
=
⋯
=
(
1
1
1
0
)
n
−
2
(
f
(
2
)
f
(
1
)
)
\left(\begin{array}{c}f(n) \\ f(n-1)\end{array}\right)=\left(\begin{array}{cc}1 & 1 \\ 1 & 0\end{array}\right)\left(\begin{array}{c}f(n-1) \\ f(n-2)\end{array}\right)=\cdots=\left(\begin{array}{cc}1 & 1 \\ 1 & 0\end{array}\right)^{n-2}\left(\begin{array}{c}f(2) \\ f(1)\end{array}\right)
(f(n)f(n−1))=(1110)(f(n−1)f(n−2))=⋯=(1110)n−2(f(2)f(1))
因而计算f(n)就简化为了计算矩阵的(n-2)次方,而计算矩阵的(n-2)次方,我们又可以进行分解,即计算矩阵(n-2)/2次方的平方,逐步分解下去,由于折半计算矩阵次方,因而时间复杂度为O(log n)