Hello算法2:复杂度分析

Hello算法2:复杂度分析

本文是基于k神的Hello 算法的读书笔记,请支持实体书。
https://www.hello-algo.com/chapter_paperbook/

算法效率

算法效率评估

设计算法时,我们追求以下两个目标:

  • 找出解法
  • 找出最优解

最优解通常包含两个指标:

  • 时间:算法运行的时间
  • 空间:算法占用的内存

评估的方法分为两种:

实际测试和理论评估

实际测试

找一台计算机实际运行代码,比较两个算法的效率。

这样虽然很直观,但是有以下缺陷

  • 难以排除测试环境的干扰:两台计算机配置不同,在上面运行某算法可能会得到不同的结果
  • 完整的测试很耗费资源:某些算法对于少量数据和巨量数据表现差别很大,这就需要设计测试时尽量覆盖所有情况

理论估算

也就是复杂度分析,它描述随着输入数据大小的增加,算法执行的时间和空间的增长趋势。

它客服了实际测试的缺点,体现如下:

  • 无需测试环境,结果适用于各平台
  • 可以体现不同数据量下的效率,特别是针对大数据

迭代和递归

在执行算法时,重复执行某个任务很常见。

迭代

常见的迭代有for循环和while循环

for循环

比如计算1+2+n的值,for循环的时间复杂度取决于n的值,它是线性相关的

while循环

初始化条件和条件更新的步骤独立于循环过程,所以while循环更自由

循环的嵌套

循环中可以嵌套循环,此时复杂度就变成了n的平方

递归

递归是指通过调用函数自身来解决问题,主要包含两个阶段

  1. 递:不断深入的调用自身,通常是不断传入更小的参数,直到达到终止条件
  2. 归:触发终止条件后,程序开始逐层返回
def recur(n: int) -> int:
    """递归"""
    # 终止条件
    if n == 1:
        return 1
    # 递:递归调用
    res = recur(n - 1)
    # 归:返回结果
    return n + res

调用栈

每次调用自身,计算机都会开辟新的内存区域,存储局部变量、调用地址和其他变量,因此

  • 递归通常比迭代更耗费内存空间
  • 递归的时间效率通常更低

递归深度过多,可能会溢出

尾递归

在返回前的最后一步才进行递归调用中调用自身,这种方式某些语言可以被编译器或解释器优化,使其在空间效率上与迭代相当。但比如python就不支持。

def tail_recur(n, res):
    """尾递归"""
    # 终止条件
    if n == 0:
        return res
    # 尾递归调用
    return tail_recur(n - 1, res + n)

递归树

以“斐波那契数列”为例,将会产生如下的递归树

给定一个斐波那契数列0,1,1,2,3,5,8,13,…,求该数列的第n个数字

def fib(n: int) -> int:
    """斐波那契数列:递归"""
    # 终止条件 f(1) = 0, f(2) = 1
    if n == 1 or n == 2:
        return n - 1
    # 递归调用 f(n) = f(n-1) + f(n-2)
    res = fib(n - 1) + fib(n - 2)
    # 返回结果 f(n)
    return res

在这里插入图片描述

时间增长趋势

如下三个算法:

# 算法 A 的时间复杂度:常数阶
def algorithm_A(n: int):
    print(0)
# 算法 B 的时间复杂度:线性阶
def algorithm_B(n: int):
    for _ in range(n):
        print(0)
# 算法 C 的时间复杂度:常数阶
def algorithm_C(n: int):
    for _ in range(1000000):
        print(0)

时间增长趋势如下:

在这里插入图片描述

可以看出时间复杂度有如下特点:

  • 可以有效评估算法效率
  • 时间复杂度的推算更简便
  • 存在一定局限性

计算方式

第一步:统计操作数量,有以下技巧

  1. 忽略常数项
  2. 省略所有系数
  3. 循环嵌套时使用乘法
def algorithm(n: int):
    a = 1      # +0(技巧 1)
    a = a + n  # +0(技巧 1)
    # +n(技巧 2)
    for i in range(5 * n + 1):
        print(0)
    # +n*n(技巧 3)
    for i in range(2 * n):
        for j in range(n + 1):
            print(0)

应用上述方法后,可得操作数量是

在这里插入图片描述

第二步:逐渐判断上界

时间复杂度由 T(n) 中最高阶的项来决定。这是因为在 n 趋于无穷大时,最高阶的项将发挥主导作用,其他项的影响都可以忽略。

常见有如下复杂度:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/496721.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Douyin视频详情数据API接口(视频详情,评论)

抖音官方并没有直接提供公开的视频详情数据采集API接口给普通用户或第三方开发者。抖音的数据采集通常受到严格的限制,以保护用户隐私和平台安全。 请求示例,API接口接入Anzexi58 如果您需要获取抖音视频详情数据,包括评论、点赞等&#xff…

VMware虚拟机更换引导顺序

前言 我用wmware装了黑群晖测试,将img转成vmdisk的格式之后发现系统引导盘之后1G,有点太小了 我准备把wmware的黑群晖系统迁移到新添加的虚拟磁盘里 1.登录黑群晖的SSH 请先在黑群晖的控制面板中的终端机和SNMP里面启用SSH功能,才能使用ss…

创新指南|如何将人工智能应用于未来的创新管理——并不断付诸实践

ChatGPT 的推出加剧了围绕人工智能的炒作,现在我们看到了前所未有的巨大进展。对于我们这些热衷于创新的人来说,这是一个激动人心的时刻。他们正在共同采取措施,充分利用人工智能进行创新管理。本文将阐述人工智能能为创新管理做什么&#xf…

《米小圈动画汉字》—“动起来”汉字就能轻松记住啦!

为了迎合孩子们的兴趣,市面上推出了许多类型的动画片,所谓“动画”是让角色动起来,感染孩子,给孩子带来欢乐。但是,并不是所有动画片都对孩子有益,市面上的大多良莠不齐,孩子分辨不了还可能影响…

2020年天津市二级分类土地利用数据(矢量)

天津市,位于华北平原海河五大支流汇流处,东临渤海,北依燕山。地势以平原和洼地为主,北部有低山丘陵,海拔由北向南逐渐下降,地貌总轮廓为西北高而东南低。天津有山地、丘陵和平原三种地形,平原约…

代码随想录算法训练营三刷day37 | 贪心 之 738.单调递增的数字 968.监控二叉树

三刷day37 738.单调递增的数字968.监控二叉树确定遍历顺序如何隔两个节点放一个摄像头情况1:左右节点都有覆盖情况2:左右节点至少有一个无覆盖的情况情况3:左右节点至少有一个有摄像头情况4:头结点没有覆盖 738.单调递增的数字 题…

中国国际通信大会2024|中国通信展览会|通信展览会

中国国际通信大会2024|中国通信展览会|通信展览会 中国国际信息通信展览会(ICT展)是亚太地区最具影响力的信息通信技术盛会之一。每年一度的ICT展汇聚了来自全球各行各业的专业人士,为各领域的科技公司、创新企业以及技术爱好者们提供一个难得…

VS2022 使用ClaudiaIDE设置自定义图片背景

ClaudiaIDE的下载 第一步,如下图所示,点击:扩展——管理扩展。 第二步,如下图所示,点击:联机——右上角输入ClaudiaIDE搜索——点击下载。 下载后关闭所有VS窗口,然后等待弹出一个安装窗口&…

RAFT:让大型语言模型更擅长特定领域的 RAG 任务

RAFT(检索增强的微调)代表了一种全新的训练大语言模型(LLMs)以提升其在检索增强生成(RAG)任务上表现的方法。“检索增强的微调”技术融合了检索增强生成和微调的优点,目标是更好地适应各个特定领…

机器学习——元学习

元学习(Meta Learning)是一种机器学习方法,旨在使模型能够学习如何学习。它涉及到在学习过程中自动化地学习和优化学习算法或模型的能力。元学习的目标是使模型能够从有限的训练样本中快速适应新任务或新环境。 在传统的机器学习中&#xff…

2024社工考试报名详细流程来啦✅

2024社工考试报名详细流程来啦✅ ⏰社工报名时间:4月1日-4月18日 👇🏻2024年社工报名流程 1、打开人事考试网,点击左侧【网上报名】 2、没有用户名的点击新用户注册,有用户名的直接输入用户名密码登录即可。 3、注册好…

RK3568-开启ptp服务

硬件支持 mac或者phy需要支持ptp驱动支持 CONFIG_PTP_1588_CLOCK=y虚拟机端:虚拟机只支持软件时间戳。 安装ptp服务:sudo apt-get install linuxptpbuildroot系统-开发板端:开发板支持硬件时间戳和软件时间戳。 BR2_PACKAGE_LINUXPTP=y 编译相关ptp4l程序ubuntu系统-开发…

【Web前端】CSS基本语法规范和引入方式常见选择器用法常见元素属性

一、基本语法规范 选择器 {一条/N条声明} 选择器决定针对谁修改 (找谁) 声明决定修改什么.。(干什么) 声明的属性是键值对.。使用 &#xff1a; 区分键值对&#xff0c; 使用 &#xff1a; 区分键和值。 <!DOCTYPE html> <html lang"en"> <head>&…

PXE批量装centos7系统

1.环境准备&#xff1a; yum -y install tftp-server xinetd #安装并启用 TFTP 服务 #修改TFTP服务的配置文件 vim /etc/xinetd.d/tftp protocol udp # TFTP默认使用UDP协议 wait no # no表示客户机可以多台一起连接&…

通过Caliper进行压力测试程序,且汇总压力测试问题解决

环境要求 第一步. 配置基本环境 部署Caliper的计算机需要有外网权限;操作系统版本需要满足以下要求:Ubuntu >= 16.04、CentOS >= 7或MacOS >= 10.14;部署Caliper的计算机需要安装有以下软件:python 2.7、make、g++(gcc-c++)、gcc及git。第二步. 安装NodeJS # …

Linux用户及用户组权限

一、用户和用户组 功能项命令实例作用用户组cat /etc/group查看当前系统存在的用户组groupadd testing添加一个新的用户组testingcat /etc/group查看组是否被新增成功groupmod -n test testing将testing重命名成testgroupdel test删除组testgroups root查看用户root所在的所有…

爱上数据结构:顺序表和链表

一、线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条…

python知识点总结(十)

python知识点总结十 1、装饰器的理解、并实现一个计时器记录执行性能&#xff0c;并且将执行结果写入日志文件中2、队列和栈的区别&#xff0c;并且用python实现3、设计实现遍历目录与子目录4、CPU处理进程最慢的情况通常发生在以下几种情况下&#xff1a;5、CPU处理线程最慢的…

iOS客户端自动化UI自动化airtest+appium从0到1搭建macos+脚本设计demo演示+全网最全最详细保姆级有步骤有图

Android客户端自动化UI自动化airtest从0到1搭建macos脚本设计demo演示全网最全最详细保姆级有步骤有图-CSDN博客 避坑系列-必读&#xff1a; 不要安装iOS-Tagent &#xff0c;安装appium -这2个性质其实是差不多的都是为了安装wda。注意安装appium最新版本&#xff0c;安装完…

洛谷 P1379 八数码难题

代码如下&#xff1a; #include<bits/stdc.h> using namespace std; struct node{string s;int pos; }star,en; map<string,int>mp[2]; queue<node>q[2]; int main(){cin>>star.s;en.s"123804765";for(int i0;i<9;i){if(star.s[i]0) sta…
最新文章