算法的时间复杂度(王道笔记)

首先解释下时间复杂度为什么得在运行前估计,主要原因有以下几点:
  1. 大家的机器性能不同,同样的程序不同机器跑出来时间不一样
  2. 使用的编程语言不同,往往越高级的语言效率越低,例如Java效率就要比C低,因为Java是更高级的语言
  3. 和编译程序产生的机器指令质量有关
  4. 有些事情是不能去事后统计的,例如重要军事的精确测量
我们估算法的时间复杂度,事实上是要探求算法时间开销T(n)与问题规模(n)的关系—>T=T(n)

举个栗子
//算法一
void loveyou(int n){     //n为问题规模
	int i = 1;
	while(i <= n){
		i++;
		printf("I Love You %d\n",i);
	}
	printf("I Love You More Than %d\n",n);
}

int main(){
loveyou(3000);
}

依次看各个语句的执次数
int i = 1 —>1次
while(i<=n)—>3001次
i++,printf(“I Love You %d\n”,i)—>3000次
printf(“I Love You More Than %d\n”,n);—>1次
共计=T(3000)=1+3001+23000+1=33000+3
将3000换成n,则T(n)=3n+3
这是一个非常简单的表达式,但当我们遇到更复杂的表达式,例如:
T1(n)=n²+3n+1000
T2(n)=n³ + n²+999999999
这些表达式就相对来说复杂了,那我们可以只保留更高阶的部分来代替整个表达式吗?
答案是可以只考虑阶数高的部分,并把系数化为1,在前面套一个大O,因为和只保留高阶的表达式对比,它们最终计算结果是相近的。
总的来说,我们只需要用一个数量级来表示算法的时间复杂度就可以了,这里用大O表示法
—>T(n)=O(n), T(n)=O(n²), T(n)=O(n³)


规则

1.加法规则
多项相加时,只保留最高阶的项,且系数变为1
2.乘法规则
多项相乘,都保留
eg:T3(n)=n³+n²log₂n = O(n³) + O(n²log₂n) 这里就需要考虑谁的数量级更大就保留谁

给出常见的阶数顺序

O(1)<O(log₂n)<O(n)<O(nlog₂n)<O(n²)<O(n³)<O(2n)<O(n!)<O(nn)
所以上边的T3(n) = O(n³)

futu

口诀:常对幂指阶

对于只有几行的代码,我们可以一行行地数,但如果有好几千行这种方法就不适用了

–>
如果是顺序执行的代码(不带循环的)我们直接忽略(因为它们只会影响常数项);对于循环来说,只需要挑循环中的一个基本操作分析它的执行次数与n的关系即可;若有多层嵌套循环只需要关注最深层的循环循环了几次

练习
void loveyou(int n){     //n为问题规模
	int i = 1;
	while(i <= n){
		i=i*2;
		printf("I Love You %d\n",i);
	}
	printf("I Love You More Than %d\n",n);
}

这里每执行一次循环,i会翻倍(2->4->8->…)
设最深层循环的语句频度(总共循环的次数)为x,则由循环条件可知,循环结束时刚好满足2^x>n
x = log₂n+1
根据加法规则,T(n) = O(log₂n)

void loveyou(int flag[], int n){     //n为问题规模
	printf("I Am Iron Man\n");
	for(int i = 0;i < n; i++){  //从第一个元素开始查找
		if(flag[i] == n){      //找到元素n
			printf("I Love You %d\n",n);
			break;    //找到后立即跳出循环
		}
	}
}
//flag数组中乱序存放了1~n这些数
int flag[n] = {1,...n};
loveyou(flag,n);

对于这个问题来说,有不同的情况
1.最好情况:n在第一个位置
—最好时间复杂度T(n)= O(1)
2.最坏情况:n在最后一个位置
—最坏时间复杂度T(n)= O(n)
3.平均情况:假设n在任意一个位置的概率相同为1/n
—平均时间复杂度T(n)= O(n)
循环次数x = (1+2+3+…+n)/n=(1+n)/2
T(n)=O(x)=O(n)

很多算法执行时间与输入数据有关

一般来说,我们只考虑最坏时间复杂度以及平均时间复杂度

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫薯C菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值