当前位置: 首页 > article >正文

数据结构 ——— 常见的时间复杂度计算例题(最终篇)

目录

前言

例题1:

例题2(例题1的延申):

例题3:


前言

在前两章分析了不少常见的时间复杂度计算例题,有固定执行N次的,也有要分情况看待的

数据结构 ——— 常见的时间复杂度计算例题(上篇)-CSDN博客

数据结构 ——— 常见的时间复杂度计算例题(中篇)-CSDN博客

接下来要分析的是递归算法的时间复杂度例题


例题1:

代码演示:

long long Fac(size_t N)
{
	if (N == 0)
		return 1;

	return Fac(N - 1) * N;
}

问:计算阶乘递归 Fac 函数的时间复杂度?

代码解析:

第一次进入 Fac 函数,先进行 if 判断,判断为假,就会再次执行 Fac 函数,知道 N 为 0 就递归返回,那么也就是:

Fac(N) -> Fac(N-1) -> Fac(N-2) -> …… -> Fac(2) -> Fac(1) -> Fac(0)

执行了 N 次,且每次执行是一个 if 判断,也就是每次执行常数次,也就是 N*1 = N,得出时间复杂度函数式:

时间复杂度函数式:F(N) = N

那么直接通过时间复杂度函数式得出大O的渐进表示法:

大O渐进表示法:O(N)


例题2(例题1的延申):

代码演示:

long long FFac(size_t N)
{
	if (N == 0)
		return 1;

	// 循环1
	for (size_t i = 0; i < N; i++)
	{
		//……
	}

	return Fac(N - 1) * N;
}

问:计算阶乘递归 FFac 函数的时间复杂度?

代码解析:

和 例题1 基本类似,唯一的区别在于 例题1 的每次递归中只执行 if 语句,也就是每次递归只执行了常数次,而 例题2 的每次递归除了执行了 if 语句,还执行了 for 循环,也就是 例题2 每次递归了 1+N 次,且递归了 N 次,所以得出时间复杂度函数式:

时间复杂度函数式:F(N) = N(1+N) = N^2 + N

由时间复杂度函数式和大O的渐进表示法规则得出:只保留最高项(去掉 F(N) 中的 N )得出大O的渐进表示法:

大O渐进表示法:O(N^2)


例题3:

代码演示:

long long Fib(size_t N)
{
	if (N < 3)
		return 1;

	return Fib(N - 1) + Fib(N - 2);
}

问:计算斐波那契递归 Fib 函数的时间复杂度?

代码解析:

最开始进入 Fib(N) 函数,先进行 if 判断,判断为假的话,就会执行 Fib(N-1) 和 Fib(N-2) ,而 Fib(N-1) 又会执行 Fib(N-2) 和 Fib(N-3) ,且 Fib(N-2) 就会执行 Fib(N-3) 和 Fib(N-4)……,以此类推,得出以下类似直角三角形的表达式:

2^0   ——   Fib(N)

2^1   ——   Fib(N-1)                 Fib(N-2)

2^2   ——   Fib(N-2) Fib(N-3)   Fib(N-3) Fib(N-4)

………………………………………………………………

2^(N-4)   ——   Fib(4) ……………………………

2^(N-3)   ——   Fib(3) Fib(2) …………

2^(N-2)   ——   Fib(2) Fib(1) 

由以上的表达式得出时间复杂度函数式:

时间复杂度函数式:F(N) = 2^0 + 2^1 + 2^2 + …… + 2^(N-4) + 2^(N-3) + 2^(N-2) 

化简时间复杂度函数式(错位相减法):

等式两边同乘2:

2*F(N) = 2^1 + 2^2 + 2^3 + …… + 2^(N-3) + 2^(N-2) + 2^(N-1)

错位相减:

2*F(N) =           2^1 + 2^2 + 2^3 + ……...... + 2^(N-3) + 2^(N-2) + 2^(N-1)

   F(N) = 2^0 + 2^1 + 2^2 + …… + 2^(N-4) + 2^(N-3) + 2^(N-2)

得:

F(N) = -1 + 2^(N-1) = 2^(N-1) -1

再根据时间复杂度函数式和大O的渐进表示法的规则推导出大O的渐进表示法:只保留最高阶项(除去 F(N) 中的 1 ) ;如果最高阶项存在且不是1,则去除与这个项目相乘的常数(除去 F(N) 中的1 ),得出大O的渐进表示法:

大O渐进表示法:O(2^N) 


结论

计算代码的时间复杂度时,不论代码是固定执行的次数,还是要分情况看待,还是递归执行,都要先推导出时间复杂度的函数式,再根据时间复杂度函数式和大O的渐进表示法的规则推导出大O的渐进表示法。


http://www.kler.cn/a/315915.html

相关文章:

  • Postman接口测试(断言、关联、参数化、输出测试报告)
  • react-rnd的使用(react使用拖拽,缩放组件)
  • 从H264视频中获取宽、高、帧率、比特率等属性信息
  • 卷积、频域乘积和矩阵向量乘积三种形式之间的等价关系与转换
  • 传奇996_19——常用函数
  • 简单叙述 Spring Boot 启动过程
  • Linux驱动开发 ——架构体系
  • 求最大公约数
  • CSS 布局三大样式简单学习
  • 【解密 Kotlin 扩展函数】命名参数和默认值(十三)
  • 【深入Java枚举类:不仅仅是常量的容器】
  • 数据结构——串的模式匹配算法(BF算法和KMP算法)
  • 设计模式-装饰者模式
  • VMware虚拟机经常性卡死,打开运行一段时间后卡死,CPU占比增至100%
  • 电脑网络怎么弄动态ip :步骤详解与优势探讨
  • Tomcat系列漏洞复现
  • AI时代最好的编程语言应该选择谁?
  • vue h5 蓝牙连接 webBluetooth API
  • MySQL 中删除重复的数据并只保留一条
  • C#实现指南:将文件夹与exe合并为一个exe
  • vscode 环境搭建
  • 神经网络修剪实战
  • ubuntu安装docker compose
  • 解决 TortoiseGitPlink Fatal Error:深入解析
  • JS巧用.padStart()|.padEnd()方法用另一个字符串填充当前字符串
  • 9月16日笔记