【CS.AL】算法复杂度分析 —— 时间复杂度详解

在这里插入图片描述

文章目录

    • 1 概述
    • 2 时间复杂度的详细分析
      • 2.1 常数时间复杂度(O(1))
      • 2.2 对数时间复杂度(O(log n))
      • 2.3 线性时间复杂度(O(n))
      • 2.4 线性对数时间复杂度(O(n log n))
      • 2.5 平方时间复杂度(O(n²))
      • 2.6 指数时间复杂度(O(2^n))
      • 2.7 阶乘时间复杂度(O(n!))
    • 3 用户体验中的时间复杂度 🔥
    • 4 计算时间复杂度的方法
    • 5 实际例子算法题
      • 5.1 二分查找算法
        • 步骤 1:分析代码
        • 步骤 2:分析循环
        • 步骤 3:处理递归
        • 步骤 4:计算总时间
        • 步骤 5:简化结果
      • 5.2 另一个例子:冒泡排序
        • 步骤 1:分析代码
        • 步骤 2:分析循环
        • 步骤 3:处理递归
        • 步骤 4:计算总时间
        • 步骤 5:简化结果
    • References

1 概述

时间复杂度是衡量一个算法执行效率的重要指标,它描述了算法在输入规模增长时,所需执行时间的增长趋势。时间复杂度通常用大O记号表示,比如O(1)、O(n)、O(n²)、O(log n)等。以下是一些常见的时间复杂度及其含义:

  1. O(1) - 常数时间复杂度

    • 这种算法在输入规模增大时,执行时间保持不变,不受输入规模影响。
    • 例如:数组访问、哈希表查找。
  2. O(log n) - 对数时间复杂度

    • 这种算法的执行时间随着输入规模的增大而对数级增长,常见于二分查找等。
    • 例如:二分查找、平衡二叉树查找。
  3. O(n) - 线性时间复杂度

    • 这种算法的执行时间与输入规模成正比,即输入规模翻倍,执行时间也翻倍。
    • 例如:线性查找、遍历数组。
  4. O(n log n) - 线性对数时间复杂度

    • 这种算法的执行时间是输入规模的线性乘以对数级增长,常见于高效排序算法如快速排序、归并排序等。
    • 例如:快速排序、归并排序。
  5. O(n²) - 平方时间复杂度

    • 这种算法的执行时间随着输入规模的平方级增长,常见于简单的排序算法如冒泡排序、选择排序等。
    • 例如:冒泡排序、选择排序。
  6. O(2^n) - 指数时间复杂度

    • 这种算法的执行时间随着输入规模的指数级增长,通常出现在解决复杂的递归问题中。
    • 例如:斐波那契数列递归解法、汉诺塔问题。
  7. O(n!) - 阶乘时间复杂度

    • 这种算法的执行时间随着输入规模的阶乘级增长,通常用于解决排列和组合问题。
    • 例如:旅行商问题的暴力解法。

2 时间复杂度的详细分析

2.1 常数时间复杂度(O(1))

在这种情况下,算法的执行时间不会随着输入规模的变化而变化。无论输入的规模多大,算法都只执行一个固定数量的操作。例如,访问数组中的某个元素,或者执行一个固定的算术运算。

2.2 对数时间复杂度(O(log n))

这种复杂度通常出现在需要“二分”处理问题的算法中。常见的例子是二分查找。在每一步中,算法将输入数据分成两半,只处理其中的一半,因此执行时间随着输入规模的对数级增长。

2.3 线性时间复杂度(O(n))

在这种情况下,算法的执行时间与输入规模成正比。每一个输入元素都会被处理一次。常见的例子包括简单的循环遍历数组、线性查找等。

2.4 线性对数时间复杂度(O(n log n))

这种复杂度通常出现在一些高效的排序算法中,如快速排序和归并排序。算法将输入数据分成较小的部分(通常是对数级),然后分别处理这些部分。

2.5 平方时间复杂度(O(n²))

这种复杂度通常出现在需要嵌套循环处理问题的算法中。每一个输入元素都会与每一个其他元素进行比较和处理。常见的例子包括冒泡排序、选择排序和插入排序。

2.6 指数时间复杂度(O(2^n))

这种复杂度通常出现在一些递归算法中,每一步递归都会生成多个子问题。常见的例子包括计算斐波那契数列的递归方法、汉诺塔问题等。

2.7 阶乘时间复杂度(O(n!))

这种复杂度通常出现在需要处理所有排列和组合问题的算法中。例如,旅行商问题的暴力解法就是一个阶乘时间复杂度的例子。

3 用户体验中的时间复杂度 🔥

#用户体验 #响应时间 #刹那 #须臾

根据《摩诃僧祗律》记载:一刹那为一念,二十念为一瞬,二十瞬为一弹指,二十弹指为一罗预,二十罗预为一须臾,一日一夜有三十须臾。可知:
1 须臾 = 24 小时 / 30 = 0.8 小时 = 48 分钟
1 罗预 = 1 须臾 / 20 = 48 分钟 / 20 = 2.4 分钟 = 2 分 24 秒
1 弹指 = 1 罗预 / 20 = 2.4 分钟 / 20 = 0.12 分钟 = 7.2 秒
1 瞬 = 1 弹指 / 20 = 7.2 秒 / 20 = 0.36 秒 = 360 毫秒
1 刹那 = 1 念 = 1 瞬 / 20 = 360 毫秒 / 20 = 18 毫秒

在实际的应用开发和用户体验中,响应时间对用户体验至关重要。以下是一些常见的响应时间要求和对应的描述:

  • 刹那(Moment):刹那可以认为是几十毫秒的响应时间。在理想状态下,页内操作应在刹那间解决,例如点击按钮、切换标签等,确保用户感受到即时的响应。

  • 瞬间(Instantaneous):瞬间的响应时间在几百毫秒以内。页面跳转应在瞬间解决,用户感觉不到延迟。

  • 弹指(Blink of an Eye):弹指级别的响应时间在几秒到十秒之间。对于复杂的操作,如上传大文件或处理复杂计算,响应时间较长时需要提供进度提示,告知用户操作正在进行中,并允许用户随时中止或取消。

4 计算时间复杂度的方法

为了理解和计算算法的时间复杂度,可以将其类比为一次探险,寻找算法的时间复杂度这个“宝藏”。以下是具体步骤:

  1. 分析代码:观察代码中的每一步操作,找到它们之间的关系,以及它们执行的频率。

  2. 分析循环:使用指南针(分析循环)判断方向,计算每一步操作的次数。

  3. 处理递归:注意递归调用的频率,计算递归的深度和每次递归的操作次数。

  4. 计算总时间:将所有操作次数加总,得到整个算法的时间复杂度。

  5. 简化结果:将复杂度表达式简化,保留最高次项,忽略常数项和低次项,得到最终的时间复杂度。

通过这些步骤,我们可以准确地计算出算法的时间复杂度,从而更好地评估和优化算法的性能。

5 实际例子算法题

让我们通过一个实际例子来演示如何计算算法的时间复杂度。

5.1 二分查找算法

int binarySearch(int arr[], int left, int right, int x) {while (left <= right) {int mid = left + (right - left) / 2;// 检查x是否在中间位置if (arr[mid] == x) return mid;// 如果x更大,忽略左半部分if (arr[mid] < x) left = mid + 1;// 如果x更小,忽略右半部分elseright = mid - 1;}// 元素不存在于数组中return -1;
}
步骤 1:分析代码
  • 初始化中间位置 mid = left + (right - left) / 2
  • 比较 arr[mid]x
  • 更新 leftright 以缩小搜索范围
步骤 2:分析循环
  • while循环条件为 left <= right,在每次迭代中,搜索范围减半。
步骤 3:处理递归

二分查找算法是一个迭代过程,没有递归调用。

步骤 4:计算总时间

在每次迭代中,搜索范围减半,这意味着我们最多会执行 log₂n 次迭代,其中 n 是数组的长度。

步骤 5:简化结果

忽略常数项和低次项,我们得到时间复杂度为 O(log n)

5.2 另一个例子:冒泡排序

void bubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {// 交换 arr[j] 和 arr[j+1]int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}
步骤 1:分析代码
  • 两个嵌套的for循环
  • 内循环中,每次迭代比较并交换相邻的元素
步骤 2:分析循环
  • 外循环执行 n-1
  • 内循环执行 n-i-1 次,其中 i 是外循环的当前迭代次数
步骤 3:处理递归

冒泡排序是一个迭代过程,没有递归调用。

步骤 4:计算总时间

总的执行次数为:∑i=0n-1​(n−i−1)=n(n−1)/2

步骤 5:简化结果

忽略常数项和低次项,我们得到时间复杂度为 O(n²)

References

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序的基本结构、cout语句(c++语言)

一、如何下载Dev C 登录网站&#xff1a;ht.51goc.com 二、安装Dev C 一、启动Dev C 双击桌面的图标 二、新建一个程序 三、复制一个程序 请你复制以下代码到“程序编辑区” #include<bits/stdc.h> using namespace std; int main() { cout<<"Hell…

计网仿真综合实验 实验十二

实验十二 综合网络实验 实验过程 IP配置说明参考连线配置OSPF使公司内部联通 路由器R1的OSPF配置路由器R2的OSPF配置路由器R3的OSPF配置R1、R2、R3的相关解释路由器R4的OSPF配置路由器R5的OSPF配置路由器R6的OSPF配置R4、R5、R6解释: 路由器R2的RIP配置路由器R7的RIP配置 总结 …

MicroPython esp32 连接wifi 配网

整体流程&#xff1a; 1&#xff09;开启STA 和 AP 模式 2&#xff09;扫描周围wifi 保存在 变量 wifi_list&#xff08;后面要用到&#xff09; 3) 尝试STA模式连接Wifi&#xff0c;并查寻状态。 4) 如果STA 无法连网&#xff0c;就用AP模式&#xff0c;创建热点。 5&a…

【lesson1】第三方库(jsoncpp,bundle, httplib)的介绍和使用

文章目录 jsoncpp库json 认识jsoncpp 认识jsoncpp 实现序列化jsoncpp 实现反序列化 bundle库bundle库实现文件压缩bundle库实现文件解压缩 httplib 库httplib 库搭建简单服务器httplib库搭建简单客户端 jsoncpp库 json 认识 json 是一种数据交换格式&#xff0c;采用完全独立…

【Vscode配置java环境并配置stringboot】

1.VSCODE配置JAVA环境 参考这篇文章配置JAVA环境&#xff1a;连接 java版本&#xff0c;我是win11系统,我下载的JAVA安装版本是下面&#xff0c;是最新版的&#xff1a; 配置环境&#xff1a;步骤很简单&#xff0c;就是向系统环境变量中添加路径&#xff0c;参考上面文章中的…

基于学习模型的可学习小波变换方法(Pytorch)

首先以图像编码为例进行说明。 图像编码是一个复杂的系统&#xff0c;通常包含多个模块&#xff0c;其中变换模块具有重要作用。小波变换在图像编码领域得到了广泛的应用&#xff0c;例如著名的JPEG 2000就是一种小波图像编码方法。然而&#xff0c;现阶段的小波图像编码方法与…

htb-window-1-legacy-smb

nmap smb-vuln-ms08-067 py文件测试失败 msf 漏洞定位 反弹 获取flag

【Oracle篇】rman全库异机恢复:从单机环境到RAC测试环境的转移(第五篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

一文学会Spring 实现事务,事务的隔离级别以及事务的传播机制

目录 一.Spring (Spring Boot) 实现事务 1.通过代码的方式手动实现事务 (手动档的车) 2.通过注解的方式实现声明式事务 (自动挡的车) 二.事务的4大特性(ACID) 三.事务的隔离级别 ①Mysql的事务隔离级别: ②Spring的事务隔离级别: 四.事务的传播机制 ①事务传播机制的概…

验证码案例

目录 前言 一、Hutool工具介绍 1.1 Maven 1.2 介绍 1.3 实现类 二、验证码案例 2.1 需求 2.2 约定前后端交互接口 2.2.1 需求分析 2.2.2 接口定义 2.3 后端生成验证码 2.4 前端接收验证码图片 2.5 后端校验验证码 2.6 前端校验验证码 2.7 后端完整代码 前言…

基于可解释性深度学习的马铃薯叶病害检测

数据集来自kaggle文章&#xff0c;代码较为简单。 import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)# Input data files are available in the read-only "../input/" directory # For example, runni…

快团团供货大团长如何查看帮卖团长的订单?

一、功能说明 可以看到团购中每个帮卖团长帮卖产生的订单 二、具体设置方法 1、小程序端如何操作&#xff1f; 在团购页面中&#xff0c;点击订单管理&#xff0c;在这里可以选择全部团长订单&#xff0c;我的团订单&#xff0c;和帮卖团长的帮卖订单。 2、PC端如何操作&am…

ssm616基于vue.js的购物商场的设计与实现+vue【已测试】

前言&#xff1a;&#x1f469;‍&#x1f4bb; 计算机行业的同仁们&#xff0c;大家好&#xff01;作为专注于Java领域多年的开发者&#xff0c;我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源&#xff1a; &#x1f469;‍&#x1f4bb; SpringBoot…

【基于C++与OpenCV实现魔方图像识别和还原算法】施工总览图

文章目录 主要效果展示思维导图魔方还原算法 本系列博客长期更新&#xff0c;分为两大部分 OpenCV实现魔方六面识别 C编写科先巴二阶段还原算法实现三阶魔方的还原 主要效果展示 摄像头识别六面 3D图像构建&#xff0c;提供还原公式 动画演示还原过程 思维导图 魔方还原算法 参…

达梦8 开启物理逻辑日志对系统的影响

物理逻辑日志&#xff0c;是按照特定的格式存储的服务器的逻辑操作&#xff0c;专门用于 DBMS_LOGMNR 包挖掘获取数据库系统的历史执行语句。当开启记录物理逻辑日志的功能时&#xff0c;这部分日志内 容会被存储在重做日志文件中。 要开启物理逻辑日志的功能&#xff0c;需要…

社区物资交易互助平台的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;公告信息管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;论坛&#xff0c;求助留言板&#xff0c;公…

SQL Chat:从SQL到SPEAKL的数据库操作新纪元

引言 SQL Chat是一款创新的、对话式的SQL客户端工具。 它采用自然语言处理技术&#xff0c;让你能够像与人交流一样&#xff0c;通过日常对话的形式对数据库执行查询、修改、创建及删除操作 极大地简化了数据库管理流程&#xff0c;提升了数据交互的直观性和效率。 在这个框…

反AI浪潮中的新机遇:Cara艺术社区异军突起

近日,一个名为Cara的艺术社区在网络上迅速走红,其独特的反AI定位吸引了大量创意人士。在AI技术日益普及的今天,Cara社区反其道而行之,致力于打造一个无AI侵害的创作和交流环境。这一创新模式不仅赢得了艺术家的青睐,也为国内创业者提供了新的思考角度。 一、精准定位,守…

C++ list链表的使用和简单模拟实现

目录 前言 1. list的简介 2.list讲解和模拟实现 2.1 默认构造函数和push_back函数 2.2 迭代器实现 2.2.1 非const正向迭代器 2.2.2 const正向迭代器 2.2.3 反向迭代器 2.3 插入删除函数 2.3.1 insert和erase 2.3.2 push_back pop_back push_front pop_front 2.4 构…

[word] word如何清除超链接 #媒体#笔记#知识分享

word如何清除超链接 办公中&#xff0c;少不了使用word&#xff0c;这个是大家必备的软件&#xff0c;今天给大家分享下word如何清除超链接的操作办法&#xff0c;一起来学习下吧&#xff01; 1、清除所有超链接 按下组合键CtrlshiftF9&#xff0c;就可以将网上复制带有超链…