数据结构
时间复杂度计算技巧
时间复杂度分析中的常见问题与计算技巧。
收录于
§ 201 时间复杂度计算技巧#
一、问题#
时间复杂度不想逐行死数代码怎么办?遇到递归根本不知道从哪里下手。
二、为什么是这样#
时间复杂度的本质是”随 增长,核心操作被执行了多少次”,大 O 最终只保留最高阶,常数和低阶项都扔掉。所以分析的重点不是”有几行代码”,而是控制结构如何放大执行次数:
顺序结构:取最大。两段分别 和 ,整体 。
循环结构:看循环变量如何接近边界。
| 循环形式 | 复杂度 |
|---|---|
i++ 到 | |
i *= 2 到 |
判对数阶的信号:每轮把规模乘以/除以一个固定常数。
嵌套循环:看内外层是否独立。独立则相乘;内层次数依赖外层则求和。
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++) {} // 总次数 0+1+...+(n-1) = n(n-1)/2 → O(n²)c递归结构:先写递推式 ,再用递归树看每层总代价。
| 递推式 | 复杂度 | 原因 |
|---|---|---|
| 深度 ,每层常数 | ||
| 每次折半 | ||
| 共 层,每层总代价 |
注意递归时间复杂度(总调用次数)和空间复杂度(最大递归深度)是两个不同的事。
三、关联#
- 0.2 算法和算法评价:大 O 记号的形式定义,语句频度的概念
四、我的理解#
口诀:顺序看最大,循环看次数,嵌套看乘积,分支看最坏,递归写递推。
遇到递归不要直接想”代码怎么跑”,而是先翻译成 的递推式,然后画两三层递归树,数清楚每层有几个节点、每个节点做多少工作,规律就出来了。
一个容易误判的例子:外层 i 翻倍( 次),内层跑 次,总次数是 ,整体是 而不是 ——因为内层不是每次都跑 次。