赞
踩
∑ i = 0 n f ( i ) ∼ ∫ i = 0 i = n f ( i ) d i \sum_{i=0}^nf(i)\sim\int_{i=0}^{i=n}f(i) di i=0∑nf(i)∼∫i=0i=nf(i)di
一般地:
∑
i
=
0
n
f
(
i
)
≤
∫
i
=
0
i
=
n
f
(
i
)
d
i
\sum_{i=0}^nf(i)\le\int_{i=0}^{i=n}f(i) di
i=0∑nf(i)≤∫i=0i=nf(i)di
T ( n ) = a T ( n / b ) + f ( n ) T(n)=aT(n/b)+f(n) T(n)=aT(n/b)+f(n)
通解为:
T
(
n
)
=
n
log
b
a
T
(
1
)
+
∑
i
=
0
⌈
log
b
n
⌉
a
i
f
(
n
/
b
i
)
T(n)=n^{\log_ba}T(1)+\sum_{i=0}^{\lceil\log_bn\rceil}a^if(n/b^i)
T(n)=nlogbaT(1)+i=0∑⌈logbn⌉aif(n/bi)
其中 ⌈ log b n ⌉ = log b n − 1 \lceil\log_bn\rceil=\log_bn-1 ⌈logbn⌉=logbn−1,求和部分直接用积分近似计算即可
衡量算法效率参数 | 数学语言 | 表示 |
---|---|---|
大 O O O法 | f ( n ) ≤ c g ( n ) f(n)\le cg(n) f(n)≤cg(n) | O ( g ( n ) ) O(g(n)) O(g(n)) |
大 Θ \Theta Θ法 | c 1 g ( n ) ≤ f ( n ) ≤ c 2 g ( n ) c_1g(n)\le f(n)\le c_2g(n) c1g(n)≤f(n)≤c2g(n) | Θ ( g ( n ) ) \Theta(g(n)) Θ(g(n)) |
大 Ω \Omega Ω法 | f ( n ) ≥ c g ( n ) f(n)\ge cg(n) f(n)≥cg(n) | Ω ( g ( n ) ) \Omega(g(n)) Ω(g(n)) |
近似法 | lim i → 0 = f ( n ) / g ( n ) = 1 \lim_{i\to0}=f(n)/g(n)=1 limi→0=f(n)/g(n)=1 | ∼ g ( n ) \sim g(n) ∼g(n) |
其中大 O O O法和大 Ω \Omega Ω法,常用于时间复杂度的标度。一般来说,时间复杂度用 O O O。
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
...
用求和表示:
T
(
n
)
=
∑
i
=
0
n
−
1
∑
j
=
0
n
−
1
1
T(n)=\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}1
T(n)=i=0∑n−1j=0∑n−11
计算时间复杂度:
法①:
T
(
n
)
=
∑
i
=
0
n
−
1
∑
j
=
0
n
−
1
1
=
∑
i
=
0
n
−
1
(
n
−
1
−
0
+
1
)
=
n
∑
i
=
0
n
−
1
1
=
n
2
T(n)=\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}1=\sum_{i=0}^{n-1}(n-1-0+1)=n\sum_{i=0}^{n-1}1=n^2
T(n)=i=0∑n−1j=0∑n−11=i=0∑n−1(n−1−0+1)=ni=0∑n−11=n2
法②:
T
(
n
)
=
∑
i
=
0
n
−
1
∑
j
=
0
n
−
1
1
∼
∬
d
i
d
j
=
∫
i
=
0
i
=
n
−
1
d
i
∫
j
=
0
j
=
n
−
1
d
j
=
n
2
T(n)=\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}1\sim\iint didj=\int_{i=0}^{i=n-1}di\int_{j=0}^{j=n-1}dj=n^2
T(n)=i=0∑n−1j=0∑n−11∼∬didj=∫i=0i=n−1di∫j=0j=n−1dj=n2
故时间复杂度为
O
(
n
2
)
O(n^2)
O(n2)
for(int i = 0; i < n; i++)
for(int j = i + 1; j < n; j++)
...
用求和表示:
T
(
n
)
=
∑
i
=
0
n
−
1
∑
j
=
i
+
1
n
−
1
1
T(n)=\sum_{i=0}^{n-1}\sum_{j=i+1}^{n-1}1
T(n)=i=0∑n−1j=i+1∑n−11
计算时间复杂度
法①:
T
(
n
)
=
∑
i
=
0
n
−
1
∑
j
=
i
+
1
n
−
1
1
=
∑
i
=
0
n
−
1
(
n
−
i
−
1
)
=
n
2
/
2
−
n
/
2
∼
n
2
T(n)=\sum_{i=0}^{n-1}\sum_{j=i+1}^{n-1}1=\sum_{i=0}^{n-1}(n-i-1)=n^2/2-n/2\sim n^2
T(n)=i=0∑n−1j=i+1∑n−11=i=0∑n−1(n−i−1)=n2/2−n/2∼n2
法②:
T
(
n
)
=
∑
i
=
0
n
−
1
∑
j
=
i
+
1
n
−
1
1
∼
∬
d
i
d
j
=
∫
i
=
0
i
=
n
−
1
d
i
∫
j
=
i
+
1
j
=
n
−
1
d
j
=
∫
i
=
0
i
=
n
−
1
(
n
−
i
−
1
)
d
i
=
n
2
−
i
2
2
∣
0
n
−
1
−
n
=
n
2
/
2
−
1
/
2
∼
n
2
T(n)=\sum_{i=0}^{n-1}\sum_{j=i+1}^{n-1}1\sim\iint didj=\int_{i=0}^{i=n-1}di\int_{j=i+1}^{j=n-1}dj=\int_{i=0}^{i=n-1}(n-i-1)di=n^2-\frac{i^2}{2}|_0^{n-1}-n\\ =n^2/2-1/2\sim n^2
T(n)=i=0∑n−1j=i+1∑n−11∼∬didj=∫i=0i=n−1di∫j=i+1j=n−1dj=∫i=0i=n−1(n−i−1)di=n2−2i2∣0n−1−n=n2/2−1/2∼n2
在这里可以发现积分的结果一般比离散求和要大,这保证了时间上界,所以积分近似有效且高效。
故时间复杂度为 O ( n 2 ) O(n^2) O(n2)
直接用for循环的方法即可,但如果增量不为1的话:
while(i <= n){
i += 2;
...
}
i
i
i的变化看作是等差数列
1
3
5
.
.
.
n
1\ 3\ 5\ ...\ n
1 3 5 ... n
那么上述数列有多少项数,那么耗时就为多少:
先写出数列的递归表达式:
x
(
k
)
=
x
(
k
−
1
)
+
2
x(k)=x(k-1)+2
x(k)=x(k−1)+2
计算得出:
x
(
k
)
=
2
k
−
1
x(k)=2k-1
x(k)=2k−1
令
x
(
k
)
=
n
x(k)=n
x(k)=n,这个时候
k
=
T
(
n
)
k=T(n)
k=T(n)
T
(
n
)
=
k
=
n
+
1
2
∼
O
(
n
)
T(n)=k=\frac{n+1}{2}\sim O(n)
T(n)=k=2n+1∼O(n)
时间复杂度为
O
(
n
)
O(n)
O(n)
while(i <= n){
i *= 2;
...
}
i变量每次乘以2,同样也可以看作求和,但这个时候
i
i
i的变化为等比数列:
1
2
4
.
.
.
n
1\ 2\ 4\ ...\ n
1 2 4 ... n
同样的,令数列:
x
(
k
)
=
2
x
(
k
−
1
)
x(k)=2\ x(k-1)
x(k)=2 x(k−1)
计算得出:
x
(
k
)
=
2
k
−
1
x(k)=2^{k-1}
x(k)=2k−1
令
x
(
k
)
=
n
x(k)=n
x(k)=n,这个时候
k
=
T
(
n
)
k=T(n)
k=T(n)
T
(
n
)
=
k
=
log
n
+
1
∼
O
(
log
n
)
T(n)=k=\log n+1\sim O(\log n)
T(n)=k=logn+1∼O(logn)
时间复杂度为
O
(
log
n
)
O(\log n)
O(logn)
对于递归式,只要求出方程就可以了,一般来说难度不大,下面介绍典型递归式。
形如
T
(
n
)
=
a
T
(
n
−
b
)
+
f
(
n
)
T(n)=aT(n-b)+f(n)
T(n)=aT(n−b)+f(n)
一般采用数列不动点求出方程
比如
T
(
n
)
=
T
(
n
−
1
)
+
n
T(n)=T(n-1)+n
T(n)=T(n−1)+n
求得
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^2)
T(n)=O(n2)
比如
T
(
n
)
=
2
T
(
n
−
1
)
+
n
T(n)=2T(n-1)+n
T(n)=2T(n−1)+n
求得数列不动点
x
=
−
n
x=-n
x=−n,构造:
T
(
n
)
−
x
=
2
T
(
n
−
1
)
+
n
−
x
T(n)-x=2T(n-1)+n-x
T(n)−x=2T(n−1)+n−x
不难得到:
T
(
n
)
+
n
=
2
[
T
(
n
−
1
)
+
n
]
T(n)+n=2[T(n-1)+n]
T(n)+n=2[T(n−1)+n]
求得:
T
(
n
)
=
O
(
2
n
)
T(n)=O(2^n)
T(n)=O(2n)
什么是数列不动点?
对于一阶线性递推数列:
x n = p x n − 1 + q x_n=px_{n-1}+q xn=pxn−1+q
令 x n = x n − 1 = x x_n=x_{n-1}=x xn=xn−1=x,这个 x x x就是不动点:
x = q 1 − p x=\frac{q}{1-p} x=1−pq
因此:
x n − x = p x n − 1 + q − x x_n-x=px_{n-1}+q-x xn−x=pxn−1+q−x
化简得到:
x n − q 1 − p = p ( x n − 1 − q 1 − p ) x_n-\frac{q}{1-p}=p(x_{n-1}-\frac{q}{1-p}) xn−1−pq=p(xn−1−1−pq)
T ( n ) = a T ( n / b ) + f ( n ) T(n)=aT(n/b)+f(n) T(n)=aT(n/b)+f(n)
通解为:
T
(
n
)
=
n
log
b
a
T
(
1
)
+
∑
i
=
0
⌈
log
b
n
⌉
a
i
f
(
n
/
b
i
)
T(n)=n^{\log_ba}T(1)+\sum_{i=0}^{\lceil\log_bn\rceil}a^if(n/b^i)
T(n)=nlogbaT(1)+i=0∑⌈logbn⌉aif(n/bi)
其中 ⌈ log b n ⌉ = log b n − 1 \lceil\log_bn\rceil=\log_bn-1 ⌈logbn⌉=logbn−1,求和部分直接用积分近似计算即可
时间复杂度不难分析,只需要观察代码,然后分析是啥变量在变化,条件是啥。然后用数列表示出这个变量,那么这个数列的项数就是 时间函数,求出时间函数一切都好办辣!
对于增量不为1的情况,还是构造数列 x ( k ) x(k) x(k),解出 x ( T ( n ) ) = n x(T(n))=n x(T(n))=n这个方程就可以了!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。