首页 > 编程语言 >01-1.1.2 算法的时间复杂度

01-1.1.2 算法的时间复杂度

时间:2024-05-27 11:33:39浏览次数:28  
标签:01 Love 1.1 int 复杂度 算法 时间 printf

如何评估算法时间开销?

存在的问题

  • 和机器性能有关
  • 和编程语言有关
  • 和编译程序产生的机器指令质量有关
  • 有些算法不能事后统计运行时间的——>如导弹控制算法

算法的时间复杂度——>T=T(n)
事前预估算法时间开销T(n)问题规模n的关系(T表示“time”)

算法的时间复杂度

用算法表示“爱你三千遍”

//算法一——逐步递增型
void loveYou(int n) {  //n为问题规模
	int i = 1;  //爱你的程度
	while(i <= n){
		i++;  //每次+1
		printf("I Love You %d\n", i);
	}
	printf("I Love You More Than %d\n", n);
}

int main(){
	loveYou(3000);
}

语句频度:

  1. int i=1;——1次
  2. while(i<=n)——3001次
  3. i++;printf("I Love You %d\n", i);——3000次
  4. printf("I Love You More Than %d\n", n);——1次
    T(3000)=1+3001+2*3000+1
    时间开销与问题规模n的关系:
    T(n)=3n+3

问题:是否可以忽略表达式的某些部分?

如:
T 1 ( n ) = 3 n + 3 T_1(n)=3n+3 T1​(n)=3n+3
T 2 ( n ) = n 2 + 3 n + 1000 T_2(n)=n^2+3n+1000 T2​(n)=n2+3n+1000
T 3 ( n ) = n 3 + n 2 + 99999999 T_3(n)=n^3+n^2+99999999 T3​(n)=n3+n2+99999999
不难发现,当问题规模n足够大的时候,后面低阶的部分常数都可以被忽略掉
所以时间复杂度只需要考虑最高阶的部分
所以以上算法都可以简化为:
T 1 ( n ) = n T_1(n)=n T1​(n)=n
T 2 ( n ) = n 2 T_2(n)=n^2 T2​(n)=n2
T 3 ( n ) = n 3 T3(n)=n^3 T3(n)=n3

1)加法规则

T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n)+g(n)))
多项相加,只保留最高阶的项,且系数变为1

2)乘法规则

T(n)=T1(n) × \times ×T2(n)=O(f(n)) × \times ×O(g(n))=O(f(n) × \times ×g(n))
多项相乘,都保留
:
T 3 ( n ) = n 3 + n 2 log ⁡ 2 n = O ( n 3 ) + O ( n 2 log ⁡ 2 n ) = O ( n 3 ) T_3(n)=n^3+n^2\log_2n =O(n^3)+O(n^2\log_2n) =O(n^3) T3​(n)=n3+n2log2​n=O(n3)+O(n2log2​n)=O(n3)

常见数量级的时间复杂度排序

O ( 1 ) < O ( l o g 2 n ) < O ( n ) < O ( n l o g 2 n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1)<O(log_2n)<O(n)<O(nlog_2n)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n) O(1)<O(log2​n)<O(n)<O(nlog2​n)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

//算法二——嵌套循环型
void loveYou(int n){
	int i=1;
	while(i<=n){
		i++;
		printf("I Love You %d\n", i);
		for (int j=1; j<=n; j++){
			printf("I am Iron Man\n");
		}
	}
	printf("I Love You More Than %d\n", n);
}

外层循环执行 n n n次,内层循环执行 n 2 n^2 n2次
时间开销与问题规模 n n n的关系:
T ( n ) = O ( n ) + O ( n 2 ) = O ( n 2 ) T(n)=O(n)+O(n^2)=O(n^2) T(n)=O(n)+O(n2)=O(n2)

结论
  1. 顺序执行的代码只会影响常数项,可以忽略
  2. 只需要挑循环中的一个基本操作分析它的执行次数与 n n n的关系即可
  3. 如果有多层嵌套循环,只需关注最深层循环循环了几次

小练习

练习一

//算法三——指数递增型
void loveYou(int 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);
}

时间复杂度:
设最深层循环的语句频度(总共循环的次数)为 x x x,则
由循环条件可知,循环结束时刚好满足 2 x > n 2^x>n 2x>n
x = l o g 2 n + 1 x=log_2n+1 x=log2​n+1
T ( n ) = O ( x ) = O ( l o g 2 n ) T(n)=O(x)=O(log_2n) T(n)=O(x)=O(log2​n)

练习二

//算法四——搜索数字型
void loveYou(int flag[], int 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)

时间复杂度:

  • 最好情况:元素n在第一个位置——最好时间复杂度T(n)=O(1)
  • 最坏情况:元素n在最后一个位置——最坏时间复杂度T(n)=O(n)
  • 平均情况:假设元素n在任意一个位置的概率相同为1/n——平均时间复杂度T(n)=O(n)
    循环次数:
    x = ( 1 + 2 + 3 + . . . + n ) 1 n = ( n ( 1 + n ) 2 ) 1 n = 1 + n 2 x=(1+2+3+...+n)\frac{1}{n}=(\frac{n(1+n)}{2})\frac{1}{n}=\frac{1+n}{2} x=(1+2+3+...+n)n1​=(2n(1+n)​)n1​=21+n​

知识回顾与重要考点

时间复杂度

如何计算

  1. 找到一个基本操作(最深层循环)
  2. 分析该基本操作的执行次数x与问题规模n的关系x=f(n)
  3. x的数量级O(x)就是算法时间复杂度T(n)

常用技巧

  1. 加法规则
  2. 乘法规则
  3. “常对幂指阶”

三种复杂度

  1. 最坏时间复杂度
  2. 平均时间复杂度
  3. 最好时间复杂度

标签:01,Love,1.1,int,复杂度,算法,时间,printf
From: https://blog.csdn.net/G2Esports_NiKo/article/details/139233572

相关文章

  • 57天【代码随想录算法训练营34期】第十章 单调栈part01
    739.每日温度单调栈指的是只增加或只减少的stack,相当于一个memoclassSolution:defdailyTemperatures(self,temperatures:List[int])->List[int]:answer=[0]*len(temperatures)stack=[0]foriinrange(1,len(temperatures)):......
  • jenkins01-Jenkins安装和简单使用
    1、Jenkins简介Jenkins官网:https://www.jenkins.io/Jenkins说明文档:https://www.jenkins.io/doc/Jenkins是一款流行的开源持续集成(ContinuousIntegration)工具,广泛用于项目开发,具有自动化构建、测试和部署等功能。Jenkins是一款使用Java语言开发的开源的自动化服务器。可以......
  • 11.1文件描述符0、1、2
    11.1文件描述符文件描述符:是内核为了高效管理已被打开的文件所创建的索引,用于被打开的文件,所有执行I/O操作的系统调用都通过文件描述;文件描述符是一个简单的非负整数,用以表明每一个被进程所打开的文件,程序刚刚启动的时候,第一个打开的文件是0,第二个打开的是1,以此类推。也......
  • # [NOIP2014 提高组] 生活大爆炸版石头剪刀布
    传送锚点:https://www.luogu.com.cn/problem/P1328题目背景NOIP2014提高组D1T1题目描述石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头。如果两个人出拳一样,则不分胜负。在《生活大爆炸》第二季第8集中出现了一种石头剪刀布的升级版游戏。升级版游戏在传统的石头......
  • 【NOIP2015普及组复赛】题3:求和
    题3:求和【题目描述】一条狭长的纸带被均匀划分出了nnn个格子,格子编号从11......
  • 【NOIP2015普及组复赛】题4:推销员
    题4:推销员【题目描述】阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有NNN家......
  • End Of Live OpenSSL 1.1 vs Slow OpenSSL 3.0
    EndOfLiveOpenSSL1.1vsSlowOpenSSL3.0【英文原文】你可能已经注意到,OpenSSL1.1.1系列将于下周一(2024年5月27日)达到寿命终止(EOL)……最明智的选择是尽快切换到3.0或3.1版本。当然,我们的mORMot2OpenSSL单元在1.1和3.x分支上运行,并在运行时自适应每个......
  • 《痞子衡嵌入式半月刊》 第 101 期
    痞子衡嵌入式半月刊:第101期这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期。本期刊是开源项目(GitHub:JayHeng/pzh-mcu-bi-weekly),欢迎提交issue,投稿或推荐你知道的嵌入式那些事儿。上期回顾:《痞子衡嵌入式半月......
  • 【例0157】ask blend parameters 请求混合参数
    文章作者:里海来源网站:NX二次开发官方案例专栏简介《askblendparameters请求混合参数》这是一个NX二次开发官方小例子,下面是代码和解析。相较于混乱、未经验证的代码,官方案例能够确保开发者获得准确的开发方法,这些官方示例代码经过严格测试,能够正确地反映出NX软件的......
  • P1504 积木城堡/01背包板子
    代码:#define_CRT_SECURE_NO_WARNINGS#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<sstream>#include<string>#include<string.h>#include<iomanip>#include<stdlib.h>......