1.时间复杂度的基本计算规则
1.基本操作即只有常数项,认为其时间复杂度为O(1)
2.顺序结构,时间复杂度按加法进行计算
3.循环结构,时间复杂度按乘法进行计算
4.分支结构,时间复杂度取最大值
5.判断一个算法效率时,往往只需要关注操作数量的最高次项,其他次要项和常数项可以忽略
在没有特殊说明时,我们所分析的时间复杂度都是指最坏时间复杂度
2.单层循环
“模拟设t法”
解题步骤
- 列出循环趟数t及每轮循环i的变化值
- 找到t与i的关系
- 确定循环停止条件
- 联立两式解方程
实例
i = n*n;
whlie(i != 1)
i = i/2;
(1)列出循环趟数t及每轮循环i的变化值
t | 0 | 1 | 2 | 3 | ... | t |
i | ... |
(2)找到t与i的关系
(3)确定循环停止条件
i=1
(4)联立两式解方程
3.双层循环
“西格玛求和法”
- 列出外层循环中i(变量)的变化值
- 列出内层语句的执行次数
- 求和,写结果
实例1
int m=0,i,j;
for (i=1;i<=n;i++)
for(j=1;j<=2*i;j++)
m++;
(1)列出循环中i的变化值
1,2,3,4,5,6...n
(2)列出内层语句的执行次数
i | 1 | 2 | 3 | 4 | 5 | ... | n |
内层循环执行次数 | 2 | 4 | 6 | 8 | 10 | ... | 2n |
(3)求和,写结果
实例2
count = 0;
for (k=1;k<=n;k*=2)
for(j=1;j<=n;j++)
count ++;
我们会发现,内外层的变量并没有直接关系(内层判断条件不外层变量制约),反而和该方法接收的参数n有关,由于是两层嵌套关系,我们用“模拟设t法”求出外层的时间复杂度乘以内层的时间复杂度就是我们所要的结果。
1.对外层:
(1)列出循环趟数t及每轮循环k的变化值
t | 1 | 2 | 3 | 4 | 5 | ... | t |
k | 1 | 2 | 4 | 8 | 16 | ... |
(2)找到t与i的关系
(3)确定循环停止条件
k>n
(4)联立两式解方程
2.对内层
其实可以直接看出其时间复杂度为O(n),就不算了。
3.内外复杂度相乘
整体时间复杂度 T = O(nlog2n) 。
4.递归
翻译成单层while循环,使用我们的单层循环计算公式来计算。
int fact(int n)
{
if(n<=1) return 1;
return n*fact(n-1);
}
理解一下上述代码,其实它的含义就是
while(n>1){
n = n-1;
}
(1)列出循环趟数t及每轮循环n的变化值
t | 1 | 2 | 3 | 4 | 5 | ... | t |
n | n | n-1 | n-2 | n-3 | n-4 | ... | n-(t-1) |
(2)找到t与i的关系
n = n - (t-1)
(3)确定循环停止条件
n=1
(4)联立两式解方程
1 = n - (t-1)
t = n
时间复杂度 T = O(n)