第 2 章 算法分析
2.8 时间复杂度(4)
1. 一个较复杂的问题
例题 2.8.1 估算以下算法的时间复杂度:
void fun(int n){
int x = 0;
for(int i = 0, j = 0; i < n; i += j, j++)
x++;
}
在循环语句中,i, j
都是从 0 开始,j
的步长是 1,但 i
的步长是 j
。通过下表,观察在迭代过程中两个变量的变化(注意,先执行 i += j
)。
循环次序 | i(i+=j) | j(j++) |
---|---|---|
1 | 0+0 | 1 |
2 | 0+0+1 | 2 |
3 | 0+0+1+2 | 3 |
4 | 0+0+1+2+3 | 4 |
r | r |
因为 i < n
,所以: ,即:
所以,时间复杂度为 。
2. 多项式时间复杂度
至此,已经学习过的时间复杂度包括: ,在 013 节的练习题中还有 。这些时间复杂度之间,存在如下定性的大小关系:
其中, 等称为多项式时间复杂度(polynomial time complexity),可以统一表示为 ,且 为多项式。
在算法复杂度理论中,多项式级的运行时间成本,往往被认为是可接受的,或者是可忍受的。某问题若可以用多项式复杂度的算法求解,则称该问题是可有效求解的,或者易解的。这样的问题也称为 P 问题。
除了 P 问题之外,也就是解决问题的算法的复杂度是多项式复杂度,除此之外,还有另外一类问题,只能用指数时间复杂度的算法求解,称为 NP 问题,或者称为难解问题。
3. 指数时间复杂度
指数时间复杂度不是本课程重点,但是,考虑到学习本课的同学,将来的学习、工作或者研究过程中,一定不会仅仅局限于教材或者所谓考研大纲的知识范围,那么,也对此做个简单介绍。
例题 2.8.3 是非负整数,计算 ,其算法如下(注意,这里的算法是此计算的一种,蛮力迭代,并不是最好的算法,此处仅仅是以此为例说明指数时间复杂度)。
int power(int n){
int pow = 1;
while(0 < n--){
pow <<= 1; // pow = pow * 2
}
return pow;
}
很显然,第 4 行是基本语句,语句频度是 ,所以此算法的时间复杂度为 。
如果将输入指数 用二进制位数 作为输入规模,则时间复杂度为 。
把时间复杂度可以表示为 的,均是指数时间复杂度(exponential time complexity)。
一般认为,指数时间复杂度的算法无法真正应用于实际问题中,这类算法不是有效的算法。
本文由mdnice多平台发布