漫画:什么是时间复杂度?
一、引言时间复杂度的意义时间复杂度的意义究竟什么是时间复杂度呢让我们来想象一个场景某一天小灰和大黄同时加入了一个公司......一天过后小灰和大黄各自交付了代码两端代码实现的功能都差不多。大黄的代码运行一次要花100毫秒内存占用5MB。小灰的代码运行一次要花100秒内存占用500MB。于是......由此可见衡量代码的好坏包括两个非常重要的指标运行时间占用空间。二、基本操作执行次数四个生活场景比喻基本操作执行次数关于代码的基本操作执行次数我们用四个生活中的场景来做一下比喻场景1线性增长场景1给小灰一条长10寸的面包小灰每3天吃掉1寸那么吃掉整个面包需要几天答案自然是 3 × 10 30天。如果面包的长度是 N 寸呢此时吃掉整个面包需要 3 × n 3n 天。如果用一个函数来表达这个相对时间可以记作 T(n) 3n。场景2对数增长场景2给小灰一条长16寸的面包小灰每5天吃掉面包剩余长度的一半第一次吃掉8寸第二次吃掉4寸第三次吃掉2寸......那么小灰把面包吃得只剩下1寸需要多少天呢这个问题翻译一下就是数字16不断地除以2除几次以后的结果等于1这里要涉及到数学当中的对数以2为底16的对数可以简写为log₂16。因此把面包吃得只剩下1寸需要 5 × log₂16 5 × 4 20 天。如果面包的长度是 N 寸呢需要 5 × log₂n 5log₂n天记作 T(n) 5log₂n。场景3常数时间场景3给小灰一条长10寸的面包和一个鸡腿小灰每2天吃掉一个鸡腿。那么小灰吃掉整个鸡腿需要多少天呢答案自然是2天。因为只说是吃掉鸡腿和10寸的面包没有关系。如果面包的长度是 N 寸呢无论面包有多长吃掉鸡腿的时间仍然是2天记作 T(n) 2。场景4平方增长场景4给小灰一条长10寸的面包小灰吃掉第一个一寸需要1天时间吃掉第二个一寸需要2天时间吃掉第三个一寸需要3天时间.....每多吃一寸所花的时间也多一天。那么小灰吃掉整个面包需要多少天呢答案是从1累加到10的总和也就是55天。如果面包的长度是 N 寸呢此时吃掉整个面包需要 123...... n-1 n (1n)×n/2 0.5n² 0.5n。记作 T(n) 0.5n² 0.5n。三、从生活场景到代码实现上面所讲的是吃东西所花费的相对时间这一思想同样适用于对程序基本操作执行次数的统计。刚才的四个场景分别对应了程序中最常见的四种执行方式场景1线性执行场景1T(n) 3n执行次数是线性的。void eat1(int n) { for (int i 0; i n; i) { System.out.println(等待一天); System.out.println(等待一天); System.out.println(吃一寸面包); } }场景2对数执行场景2T(n) 5log₂n执行次数是对数的。void eat2(int n) { for (int i 1; i n; i * 2) { System.out.println(等待一天); System.out.println(等待一天); System.out.println(等待一天); System.out.println(等待一天); System.out.println(吃一半面包); } }场景3常数执行场景3T(n) 2执行次数是常量的。void eat3(int n) { System.out.println(等待一天); System.out.println(吃一个鸡腿); }场景4平方执行场景4T(n) 0.5n² 0.5n执行次数是一个多项式。void eat4(int n) { for (int i 0; i n; i) { for (int j 0; j i; j) { System.out.println(等待一天); } System.out.println(吃一寸面包); } }四、渐进时间复杂度大O表示法渐进时间复杂度有了基本操作执行次数的函数 T(n)是否就可以分析和比较一段代码的运行时间了呢还是有一定的困难。比如算法A的相对时间是T(n) 100n算法B的相对时间是T(n) 5n²这两个到底谁的运行时间更长一些这就要看n的取值了。所以这时候有了渐进时间复杂度asymptotic time complexity的概念官方的定义如下若存在函数 f(n)使得当n趋近于无穷大时T(n) / f(n)的极限值为不等于零的常数则称 f(n) 是 T(n) 的同数量级函数。记作 T(n) O(f(n))称 O(f(n)) 为算法的渐进时间复杂度简称时间复杂度。渐进时间复杂度用大写O来表示所以也被称为大O表示法。大O表示法的推导原则如何推导出时间复杂度呢有如下几个原则如果运行时间是常数量级用常数1表示只保留时间函数中的最高阶项如果最高阶项存在则省去最高阶项前面的系数。四个场景的时间复杂度推导让我们回头看看刚才的四个场景。场景1线性时间复杂度场景1T(n) 3n最高阶项为3n省去系数3转化的时间复杂度为T(n) O(n)场景2对数时间复杂度场景2T(n) 5log₂n最高阶项为5log₂n省去系数5转化的时间复杂度为T(n) O(log n)场景3常数时间复杂度场景3T(n) 2只有常数量级转化的时间复杂度为T(n) O(1)场景4平方时间复杂度场景4T(n) 0.5n² 0.5n最高阶项为0.5n²省去系数0.5转化的时间复杂度为T(n) O(n²)时间复杂度比较这四种时间复杂度究竟谁用时更长谁节省时间呢稍微思考一下就可以得出结论O(1) O(log n) O(n) O(n²)在编程的世界中有着各种各样的算法除了上述的四个场景还有许多不同形式的时间复杂度比如O(n log n), O(n³), O(m×n), O(2ⁿ), O(n!)今后遨游在代码的海洋里我们会陆续遇到上述时间复杂度的算法。五、时间复杂度的巨大差异时间复杂度的巨大差异我们来举一个例子算法A的相对时间规模是T(n) 100n时间复杂度是O(n)算法B的相对时间规模是T(n) 5n²时间复杂度是O(n²)算法A运行在小灰家里的老旧电脑上算法B运行在某台超级计算机上运行速度是老旧电脑的100倍。那么随着输入规模 n 的增长两种算法谁运行更快呢从表格中可以看出当n的值很小的时候算法A的运行用时要远大于算法B当n的值达到1000左右算法A和算法B的运行时间已经接近当n的值越来越大达到十万、百万时算法A的优势开始显现算法B则越来越慢差距越来越明显。这就是不同时间复杂度带来的差距。六、常见算法的时间复杂度理解了时间复杂度的基本概念和四种常见增长模式后让我们看看这些模式在实际算法中的应用。以下是几种常见算法及其对应的时间复杂度1. 二分查找Binary Search时间复杂度O(log n)对应增长模式对数增长场景2二分查找是一种在有序数组中查找特定元素的算法。每次比较都将搜索范围减半因此时间复杂度为对数级。int binarySearch(int[] arr, int target) { int left 0, right arr.length - 1; while (left right) { int mid left (right - left) / 2; if (arr[mid] target) return mid; if (arr[mid] target) left mid 1; else right mid - 1; } return -1; }2. 冒泡排序Bubble Sort时间复杂度O(n²)对应增长模式平方增长场景4冒泡排序通过重复遍历列表比较相邻元素并交换位置将最大元素逐步冒泡到末尾。需要两层嵌套循环时间复杂度为平方级。void bubbleSort(int[] arr) { int n arr.length; for (int i 0; i n - 1; i) { for (int j 0; j n - i - 1; j) { if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } } }3. 快速排序Quick Sort平均时间复杂度O(n log n)对应增长模式线性对数增长文中提到的 O(n log n)快速排序采用分治策略选择一个基准元素将数组分为两部分递归排序。平均情况下时间复杂度为 O(n log n)。void quickSort(int[] arr, int low, int high) { if (low high) { int pi partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi 1, high); } } int partition(int[] arr, int low, int high) { int pivot arr[high]; int i low - 1; for (int j low; j high; j) { if (arr[j] pivot) { i; int temp arr[i]; arr[i] arr[j]; arr[j] temp; } } int temp arr[i 1]; arr[i 1] arr[high]; arr[high] temp; return i 1; }4. 斐波那契数列递归Fibonacci Recursive时间复杂度O(2ⁿ)对应增长模式指数增长文中提到的 O(2ⁿ)递归计算斐波那契数列会产生指数级的时间复杂度因为存在大量重复计算。int fibonacci(int n) { if (n 1) return n; return fibonacci(n - 1) fibonacci(n - 2); }5. 数组访问Array Access时间复杂度O(1)对应增长模式常数时间场景3通过索引直接访问数组元素无论数组多大访问时间都是常数。int getElement(int[] arr, int index) { return arr[index]; // O(1) 操作 }6. 线性搜索Linear Search时间复杂度O(n)对应增长模式线性增长场景1遍历数组中的每个元素直到找到目标或遍历完所有元素。int linearSearch(int[] arr, int target) { for (int i 0; i arr.length; i) { if (arr[i] target) return i; } return -1; }通过以上示例可以看出不同算法的时间复杂度对应着我们在前面讨论的不同增长模式。理解这些模式有助于我们在实际编程中选择合适的算法优化程序性能。

相关新闻

《深入理解java虚拟机》第1章:从零开始编译 OpenJDK 7 源码

《深入理解java虚拟机》第1章:从零开始编译 OpenJDK 7 源码

1.6 实战:自己编译 JDK 想要一探 JDK 内部的实现机制,最便捷的路径之一就是自己编译一套 JDK,通过阅读和跟踪调试 JDK 源码去了解 Java 技术体系的原理,虽然门槛会高一点,但肯定会比阅读各种书籍、文章更加贴近本质。…

2026/8/11 16:15:05 阅读更多 →
如何在Windows上实现专业级三指拖拽体验:完整配置指南

如何在Windows上实现专业级三指拖拽体验:完整配置指南

如何在Windows上实现专业级三指拖拽体验:完整配置指南 【免费下载链接】ThreeFingersDragOnWindows Enables macOS-style three-finger dragging functionality on Windows Precision touchpads. 项目地址: https://gitcode.com/gh_mirrors/th/ThreeFingersDragOn…

2026/8/11 16:14:05 阅读更多 →
Unity游戏开发中Excel数据读取的完整方案与优化技巧

Unity游戏开发中Excel数据读取的完整方案与优化技巧

1. Unity中Excel数据读取的完整方案解析 在游戏开发中,Excel表格因其直观的界面和强大的数据处理能力,常被用作游戏配置数据的载体。Unity项目需要频繁读取Excel数据来驱动游戏逻辑,但原生并不直接支持Excel文件操作。本文将分享我在多个商业…

2026/8/11 16:14:05 阅读更多 →

最新新闻

终极指南:如何使用NxNandManager管理Nintendo Switch NAND存储

终极指南:如何使用NxNandManager管理Nintendo Switch NAND存储

终极指南:如何使用NxNandManager管理Nintendo Switch NAND存储 【免费下载链接】NxNandManager Nintendo Switch NAND management tool : explore, backup, restore, mount, resize, create emunand, etc. (Windows) 项目地址: https://gitcode.com/gh_mirrors/nx…

2026/8/11 17:46:15 阅读更多 →
快速掌握C#语言基础知识点(11.位运算)

快速掌握C#语言基础知识点(11.位运算)

关注我的动态 namespace _11.位运算 {internal class Program{private enum MyEnum{ VAL1 0b_00000000, //1字节VAL2 0b_00000001,VAL3 0b_11111111,VAL4 0b_00000010,VAL5 0b_00000100,}static void Main(string[] args){var yuResult MyEnum.VAL1 & MyEnum.VAL…

2026/8/11 17:46:15 阅读更多 →
OBS多路推流插件终极指南:3分钟实现一键多平台同步直播

OBS多路推流插件终极指南:3分钟实现一键多平台同步直播

OBS多路推流插件终极指南:3分钟实现一键多平台同步直播 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 你是否经常面临这样的困境:在YouTube直播时,B…

2026/8/11 17:46:15 阅读更多 →
容器任务超时重试:怎样避免把故障扩散到集群

容器任务超时重试:怎样避免把故障扩散到集群

容器任务超时重试:怎样避免把故障扩散到集群细分主题:Docker 容器化技术与镜像安全管理:异常输入、超时与重试的故障隔离分类:[工程技术]私有镜像仓库(Enterprise Container Registry)在一次存储卷扩容过程…

2026/8/11 17:46:15 阅读更多 →
Kubernetes 排障从哪拆:先看流量、调度还是依赖

Kubernetes 排障从哪拆:先看流量、调度还是依赖

Kubernetes 排障从哪拆:先看流量、调度还是依赖细分主题:Kubernetes 生产环境运维与排障实战:核心链路的逐步实现与关键代码取舍分类:[工程技术]以从单 CoreDNS 实例迁移到 NodeLocal DNSCache 为例,Endpoint 变更可能…

2026/8/11 17:46:15 阅读更多 →
技术人做创业准备:把能力短板拆成可执行的练习

技术人做创业准备:把能力短板拆成可执行的练习

技术人做创业准备:把能力短板拆成可执行的练习 本文围绕“技术人的商业思维与创业避坑指南:个人能力地图与阶段性训练计划”整理实践中的判断方法。文中没有引用具体公司、用户或线上数据;流程和字段只用于说明如何做判断,落地时…

2026/8/11 17:44:14 阅读更多 →

日新闻

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/v…

2026/8/11 0:00:02 阅读更多 →
前后端分离项目中控制台与接口工具数据差异排查指南

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析:控制台与Apifox的数据差异 最近在调试一个前后端分离项目时,遇到了一个典型问题:后端服务在本地开发环境控制台能正常输出查询数据,但通过Apifox测试时却返回空结果。这种"控制台有数据,接口工具…

2026/8/11 0:00:03 阅读更多 →
AI编程实战:从Claude Code踩坑到游戏开发入门

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友,尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友,都在问我同一个问题:“听说现在用Claude Code这种AI编程工具,小白也能做游戏了,是真的吗&#…

2026/8/11 0:00:03 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/11 1:08:05 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 1:08:05 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/11 1:08:05 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/11 17:09:45 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/11 1:08:06 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/11 17:09:45 阅读更多 →