通用规则
加法规则: T ( n ) = T 1 ( n ) + T 2 ( n ) = O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x ( f ( n ) , g ( n ) ) ) T(n)=T_{1}(n)+T_{2}(n)=O(f(n))+O(g(n))=O(max( f(n),g(n) ) ) T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))
乘法规则: T ( n ) = T 1 ( n ) × T 2 ( n ) = O ( f ( n ) ) × O ( g ( n ) ) = O ( f ( n ) × g ( n ) ) T(n)=T_{1}(n)×T_{2}(n)=O(f(n))×O(g(n))=O(f(n)×g(n)) T(n)=T1(n)×T2(n)=O(f(n))×O(g(n))=O(f(n)×g(n))
常用级数
- 收敛级数: T ( n ) = 1 + 1 2 2 + 1 3 2 + . . . + 1 n 2 < 1 + 1 2 2 + 1 3 2 + . . . = π 2 6 = O ( 1 ) T(n) = 1+\frac{1}{2^2}+\frac{1}{3^2}+...+\frac{1}{n^2} < 1 +\frac{1}{2^2}+\frac{1}{3^2}+... = \frac{π^2}{6} = O(1) T(n)=1+221+321+...+n21<1+221+321+...=6π2=O(1)
- 调和级数: T ( n ) = 1 + 1 2 + 1 3 + . . . + 1 n = O ( l o g n ) T(n) = 1+\frac{1}{2}+\frac{1}{3}+...+\frac{1}{n} = O(logn) T(n)=1+21+31+...+n1=O(logn)
- 对数级数: T ( n ) = l o g 1 + l o g 2 + l o g 3 + . . . + l o g n = O ( n l o g n ) T(n) = log1 + log2 + log3 +...+logn = O(nlogn) T(n)=log1+log2+log3+...+logn=O(nlogn)
- 算术级数: T ( n ) = 1 + 2 + . . . + n = n ( n + 1 ) 2 = O ( n 2 ) T(n) = 1 + 2 + ... + n = \frac{n(n+1)}{2} = O(n^2) T(n)=1+2+...+n=2n(n+1)=O(n2)
- 幂方级数: T ( n ) = 1 2 + 2 2 + 3 2 + . . . + n 2 = ∑ k = 0 n k 2 ≈ ∫ 0 n x 2 d x = 1 3 n 3 = O ( n 3 ) T(n) = 1^2+2^2+3^2+...+n^2 = \sum_{k=0}^{n}k^2≈\int_{0}^{n}x^{2}dx=\frac{1}{3}n^{3}=O(n^{3}) T(n)=12+22+32+...+n2=k=0∑nk2≈∫0nx2dx=31n3=O(n3)
- 几何级数: T 2 ( n ) = 1 + 2 + 4 + 8 + . . . + 2 n = ∑ k = 0 n 2 k = 2 n + 1 − 1 = O ( 2 n + 1 ) = O ( 2 n ) T_{2}(n) = 1+ 2 + 4+ 8+...+2^n =\sum_{k=0}^{n}2^k = 2^{n+1}-1 =O(2^{n+1})=O(2^n) T2(n)=1+2+4+8+...+2n=k=0∑n2k=2n+1−1=O(2n+1)=O(2n)
迭代程序
迭代程序通常使用 while
循环或 for
循环表示,两者可以等价互换,而 for
循环便于计算时间复杂度,所以遇到 while
循环时统一转换为 for
循环以计算。
1. 单层循环
解:设循环次数为 t t t,并且算法等价于 for (int i = 1; i <= n; i*=2)
。当 t = 0 t=0 t=0 时, i = 1 ( 2 0 ) i=1(2^{0}) i=1(20);当 t = 1 t=1 t=1 时, i = 2 ( 2 1 ) i=2(2^{1}) i=2(21);当 t = 2 t=2 t=2 时, i = 4 ( 2 2 ) i=4(2^{2}) i=4(22),以此类推可知循环次数 t t t 满足 2 t ≤ n 2^{t}≤n 2t≤n,因此时间复杂度为 O ( log n ) O(\log n) O(logn)
解:设循环次数为 t t t,并且算法等价于 for (int x = 2; x < n/2; x*=2)
。当 t = 0 t=0 t=0 时, x = 1 ( 2 1 ) x=1(2^{1}) x=1(21);当 t = 1 t=1 t=1 时, x = 4 ( 2 2 ) x=4(2^{2}) x=4(22);当 t = 2 t=2 t=2 时, i = 8 ( 2 3 ) i=8(2^{3}) i=8(23),以此类推可知循环次数 t t t 满足 2 t + 1 < n / 2 2^{t+1}<n/2 2t+1<n/2,因此时间复杂度为 O ( log n ) O(\log n) O(logn)
解:设循环次数为 t t t,并且算法等价于
int i = 0;
for (int sum=0; sum < n; sum += i) {
++i;
}
当 t = 0 t=0 t=0 时, i = 0 i=0 i=0, s u m = 0 sum=0 sum=0;当 t = 1 t=1 t=1 时, i = 1 i=1 i=1, s u m = 0 + 1 sum=0+1 sum=0+1;当 t = 2 t=2 t=2 时, i = 2 i=2 i=2, s u m = 0 + 1 + 2 sum=0+1+2 sum=0+1+2,以此类推可知循环次数 t t t 满足 ∑ i = t ( t + 1 ) 2 < n \sum i=\frac{t(t+1)}{2}<n ∑i=2t(t+1)<n,因此时间复杂度为 O ( n ) O( \sqrt{n}) O(n)
解:设循环次数为 t t t,并且算法等价于 for (int i = 2; i*i*i ≤ n; i++)
。当 t = 0 t=0 t=0 时, i ∗ i ∗ i = 2 3 i*i*i=2^{3} i∗i∗i=23;当 t = 1 t=1 t=1 时, i ∗ i ∗ i = 3 3 i*i*i=3^{3} i∗i∗i=33;当 t = 2 t=2 t=2 时, i = 4 3 i=4^{3} i=43,以此类推可知循环次数 t t t 满足 ( t + 2 ) 3 ≤ n (t+2)^{3}≤n (t+2)3≤n,因此时间复杂度为 O ( n 3 ) O(\sqrt[3]{n}) O(3n)
解:设循环次数为 t t t,并且算法等价于 for (int x = 0; (x+1)(x+1) ≤ n; x++)
。当 t = 0 t=0 t=0 时, ( x + 1 ) ( x + 1 ) = 1 (x+1)(x+1)=1 (x+1)(x+1)=1,即 ( t + 1 ) 2 (t+1)^{2} (t+1)2;当 t = 1 t=1 t=1 时, ( x + 1 ) ( x + 1 ) = 4 (x+1)(x+1)=4 (x+1)(x+1)=4,即 ( t + 1 ) 2 (t+1)^{2} (t+1)2;当 t = 2 t=2 t=2 时, ( x + 1 ) ( x + 1 ) = 9 (x+1)(x+1)=9 (x+1)(x+1)=9,即 ( t + 1 ) 2 (t+1)^{2} (t+1)2 ,以此类推可知循环次数 t t t 满足 ( t + 1 ) 2 ≤ n (t+1)^{2}≤n (t+1)2≤n,因此时间复杂度为 O ( n 2 ) O(\sqrt[2]{n}) O(2n)
2. 多层循环
循环变量无关:乘法规则
解:外层时间复杂度为 O ( log n ) O(\log n) O(logn),内层时间复杂度 O ( n ) O(n) O(n),乘法规则可得时间复杂度为 O ( n log n ) O(n\log n) O(nlogn)。
循环变量相关:级数
解:冒泡排序最坏情况,则所有相邻元素逆序,最后一行语句每次都执行 T ( n ) = ∑ i = 2 n − 1 ∑ j = 1 i − 1 1 = ∑ i = 2 n − 1 i − 1 = ( n − 2 ) ( n − 1 ) 2 = O ( n 2 ) T(n) =\sum_{i=2}^{n-1} \sum_{j=1}^{i-1} 1 =\sum_{i=2}^{n-1} i-1 =\frac{(n-2)(n-1)}{2} =O(n^{2}) T(n)=i=2∑n−1j=1∑i−11=i=2∑n−1i−1=2(n−2)(n−1)=O(n2)
解: T ( n ) = ∑ i = 1 n ∑ j = 1 2 i 1 = ∑ i = 1 n 2 i = 2 ∑ i = 1 n i = n ( n + 1 ) = O ( n 2 ) T(n) =\sum_{i=1}^{n} \sum_{j=1}^{2i} 1 =\sum_{i=1}^{n} 2i =2\sum_{i=1}^{n} i =n(n+1) =O(n^{2}) T(n)=i=1∑nj=1∑2i1=i=1∑n2i=2i=1∑ni=n(n+1)=O(n2)
递归程序
递归方程: 递归关系简单的方程,可借助递推关系归纳出 T(n)与T(n – 1)等的关系,不断用递推方程的右部替换左部,直至 T(1)
递归方程: T ( n ) = T ( n − 1 ) + 1 T(n)=T(n-1)+1 T(n)=T(n−1)+1
递归基: T ( 1 ) = O ( 1 ) T(1)=O(1) T(1)=O(1)
求解: T ( n ) = T ( n − 1 ) + 1 = T ( n − 2 ) + 1 + 1 = . . . = T ( 1 ) + n − 1 = O ( n ) T(n)=T(n-1)+1=T(n-2)+1+1=...=T(1)+n-1=O(n) T(n)=T(n−1)+1=T(n−2)+1+1=...=T(1)+n−1=O(n)
递归方程: T ( n ) = 2 T ( n / 2 ) + n T(n)=2T(n/2)+n T(n)=2T(n/2)+n
递归基: T ( 1 ) = O ( 1 ) T(1)=O(1) T(1)=O(1)
求解:
T ( n ) = 2 T ( n / 2 ) + n = 2 2 T ( n / 2 2 ) + 2 n = . . . = 2 log 2 n T ( 1 ) + n log 2 n = n ( log n + 1 ) = O ( n log n ) T(n)=2T(n/2)+n=2^{2}T(n/2^{2})+2n=...=2^{\log_{2} n}T(1)+n\log_{2}n=n(\log n+1)=O(n\log n) T(n)=2T(n/2)+n=22T(n/22)+2n=...=2log2nT(1)+nlog2n=n(logn+1)=O(nlogn)
递归树:递归式转换为一棵树,其结点表示不同层次的递归调用产生的代价,结点数量级即时间复杂度
解:本题精确计算方法是使用二阶常系数差分方程,但求解方法复杂,可使用递归树计算结点数量。