【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更小,忽略右半部分
        else
            right = 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

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

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

相关文章

iOS 17.5中的一个漏洞

i0S 17.5中的一个漏洞 iOS 17.5中的一个漏洞会使已刚除的照片重新出现&#xff0c;并目此问题似乎会影响甚至已擦除并出售给他人的 iPhone 和 iPad. 在2023年9月&#xff0c;一位Reddit用户根据Apple的指南擦除了他的iPad&#xff0c;并将其卖给了一位朋友。然而&#xff0c;这…

野火FPGA跟练(四)——串口RS232、亚稳态

目录 简介接口与引脚通信协议亚稳态RS232接收模块模块框图时序波形RTL 代码易错点Testbench 代码仿真 RS232发送模块模块框图时序波形RTL 代码Testbench 代码仿真 简介 UART&#xff1a;Universal Asynchronous Receiver/Transmitter&#xff0c;异步串行通信接口。发送数据时…

Sentinel1.8.6更改配置同步到nacos(项目是Gateway)

本次修改的源码在&#xff1a;https://gitee.com/stonic-open-source/sentinel-parent 一 下载源码 地址&#xff1a;https://github.com/alibaba/Sentinel/releases/tag/1.8.6 二 导入idea&#xff0c;等待maven下载好各种依赖 三 打开sentile-dashboard这个模块&#xf…

HTML开发 Vue2.x + Element-UI 动态生成表单项并添加表单校验

基于vue2.x 和element-ui 动态生成表单项并添加表单校验&#xff1b; 1、需求问题 如下图&#xff0c;项目有个需求&#xff0c;点击添加按钮&#xff0c;新增一行设备信息&#xff0c;且每项信息必填&#xff1b; 2、代码 看到这个需求&#xff0c;首先想到要使用v-for的形…

大众汽车裁员加速,38万元遣散费起步

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 几周前&#xff0c;大众汽车宣布了一项新的裁员计划。 一、裁员行动与额外福利并行 大众汽车近期在裁员行动上取得了显著进展&#xff0c;其遣散…

基于I2C协议的OLED显示(利用U82G库)

目录 一、I2C协议的基本原理和时序协议I2C通信协议的原理I2C时序基本单元I2C时序 二、建立工程RCC配置TIM1配置时钟树配置工程配置 三、U8g2移植精简u8g2_d_setup.c精简u8g2_d_memory.c编写移植函数stm32_u8g2.hstm32_u8g2.c 四、实验1.U82G的demo例程2.显示网名昵称中文取模步…

Pytorch 从零实现 Transformer

前言 之前虽然了解过 Transformer 架构&#xff0c;但是没有自己实现过。 最近阅读 transformers 库中 Llama 模型结构&#xff0c;于是想试着亲手实现一个简单的 Transformer。 在实现过程中加深了理解&#xff0c;同时发现之前阅读 Llama 中一些错误的地方&#xff0c;因此…

蓝桥杯--跑步计划

问题描述 小蓝计划在某天的日期中出现 11 时跑 55 千米&#xff0c;否则只跑 11 千米。注意日期中出现 11 不仅指年月日也指星期。 请问按照小蓝的计划&#xff0c;20232023 年小蓝总共会跑步锻炼多少千米?例如&#xff0c;55 月 11 日、11 月 1313 日、1111 月 55 日、44 月…

Linux:基本指令

文章目录 ls指令pwd指令cd指令touch指令mkdir指令rmdir指令 && rm指令cp指令man指令echo指令输出重定向追加重定向 cat指令输入重定向 mv指令which指令alias指令more && less指令head && tail指令事件相关的指令date显示时间戳 cal指令find指令grep指令…

c++之旅第十弹——IO流

大家好啊&#xff0c;这里是c之旅第十弹&#xff0c;跟随我的步伐来开始这一篇的学习吧&#xff01; 如果有知识性错误&#xff0c;欢迎各位指正&#xff01;&#xff01;一起加油&#xff01;&#xff01; 创作不易&#xff0c;希望大家多多支持哦&#xff01; 一.流的概念&…

星火秘境游戏开发链游app定制开发源码部署

星火秘境是一款神秘而充满冒险的游戏&#xff0c;开发这样一款游戏需要综合考虑多个方面&#xff0c;包括游戏设计、美术设计、程序开发、音效制作等。下面我将简要介绍一下游戏开发和链游app搭建的一般流程&#xff1a; 游戏设计&#xff1a; 确定游戏类型&#xff1a;星火秘…

雷电模拟器中控实现,直通源码

目录 前言 开发 需求 初始环境 UI搭建 功能实现 前言 本篇为易语言雷电模拟器中控项目实现操作&#xff0c;一般用于&#xff1a;脚本开发多线程模拟操作等起始模板框架&#xff0c;使用易语言原因为其前后端一体化&#xff0c;对于脚本开发而言更为方便。 开发 需求 以…

每天壁纸不重样~下载必应每日图片

下载必应每日图片 必应不知道你用过没有你下载过必应的图片没有你又没搜索过桌面图片你是不是安装过桌面图片软件你是不是为找一个好看的图片下载过很多桌面软件 必应每日图片 必应每天都会有一张不同的风景图片&#xff0c;画质清晰&#xff0c;而且不收费可以下载使用 但…

MySQL之多表查询—列子查询

一、引言 标量子查询上篇博客已学习。接下来这篇博客学习子查询的第二种形式——列子查询 列子查询 子查询返回的结果是一列&#xff08;当然也可以是多行)&#xff0c;这种子查询称为列子查询。 列子查询可以使用的操作符 IN、NOT IN 、ANY&#xff08;any&#xff09;、SOME…

计算机组成结构—IO系统概述

目录 一、I/O 系统的发展 1. 早期阶段 2. 接口模块和 DMA 阶段 3. 通道结构阶段 4. 处理机阶段 二、I/O 系统的组成 1. I/O 软件 2. I/O 硬件 三、I/O 设备 1. I/O 设备分类 2. I/O 设备的组成 在计算机中&#xff0c;除 CPU 和主存两大模块之外&#xff0c;第三个重…

C#中使用Mysql批量新增数据 MySqlBulkCopy

在C#中使用MySqlBulkCopy类来批量复制数据到MySQL数据库&#xff0c;首先需要确保你的项目中已经引用了MySQL Connector。以下是使用MySqlBulkCopy的基本步骤&#xff1a; 1.安装MySQL Connector。 可以通过NuGet安装MySQL Connector&#xff1a; 2.在代码中引用必要的命名空间…

物资材料管理系统建设方案(Word)—实际项目方案

二、 项目概述 2.1 项目背景 2.2 现状分析 2.2.1 业务现状 2.2.2 系统现状 三、 总体需求 3.1 系统范围 3.2 系统功能 3.3 用户分析 3.4 假设与依赖关系 四、 功能需求 4.4.11.7 非功能性需求 五、 非功能性需求 5.1 用户界面需求 5.2 软硬件环境需求 5.3 产品质量需求 5.4 接口…

[线程与网络] Java虚拟机常考面试题(线程与网络完结)

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;线程与…

使用 GPT-4 创作高考作文 2024年

使用 GPT-4 创作高考作文 2024年 使用 GPT-4 创作高考作文&#xff1a;技术博客指南 &#x1f914;✨摘要引言正文内容&#xff08;详细介绍&#xff09; &#x1f4da;&#x1f4a1;什么是 GPT-4&#xff1f;高考作文题目分析 ✍️&#x1f9d0;新课标I卷 人类智慧的进步&…

atomic特质的局限性

为什么在实际的 Objective-C 开发中, 几乎所有的属性都声明为 nonatomic ? 声明为 atomic 的属性我是真的没见过 在实际的 Objective-C 开发中&#xff0c;大多数属性通常声明为 nonatomic&#xff0c;主要原因包括性能考虑和常见的设计模式。具体原因如下&#xff1a; 性能问…