Skip to content

复杂度分析

本章目标:掌握大 O 表示法,能在 30 秒内估算代码的时间与空间复杂度。

你将学到

  • 大 O 表示法的定义与含义
  • 常见复杂度等级的对比
  • 空间复杂度的计算
  • 主定理(Master Theorem)及应用
  • 均摊分析的概念
  • 1 秒内能处理多大规模的数据

1. 概念

大 O 表示法描述的是算法运行时间(或空间)随输入规模 n 增长的上界。它忽略常数因子和低阶项,只关注增长趋势。例如 3n² + 5n + 100 的大 O 为 O(n²)

理解复杂度的核心在于:当 n 趋于无穷大时,哪一项主导了增长。

常见复杂度对比

复杂度名称n=10n=100n=1000n=10⁶典型算法
O(1)常数1111哈希表查找
O(log n)对数371020二分查找
O(n)线性1010010³10⁶数组遍历
O(n log n)线性对数3366410⁴2×10⁷归并排序
O(n²)平方10010⁴10⁶10¹²冒泡排序
O(2ⁿ)指数1024极大天文数字天文数字暴力求子集
O(n!)阶乘3628800天文数字全排列

1 秒能算多大 n

竞赛和面试中,通常假设每秒执行约 10⁸ 次基本运算

  • O(n):n 可达 10⁸
  • O(n log n):n 可达 10⁶
  • O(n²):n 可达 10⁴
  • O(n³):n 可达 500
  • O(2ⁿ):n 不超过 25
  • O(n!):n 不超过 12

看到题目数据范围,就应该知道需要什么复杂度的算法。

2. 主定理(Master Theorem)

用于分析分治递归 T(n) = aT(n/b) + f(n) 的复杂度:

比较 f(n) 与 n^(log_b a):

Case 1: f(n) = O(n^(log_b a - ε))  →  T(n) = Θ(n^(log_b a))
Case 2: f(n) = Θ(n^(log_b a))      →  T(n) = Θ(n^(log_b a) · log n)
Case 3: f(n) = Ω(n^(log_b a + ε))  →  T(n) = Θ(f(n))

经典例子:

  • 归并排序:T(n) = 2T(n/2) + O(n) → a=2, b=2, f(n)=n → Case 2 → O(n log n)
  • 二分查找:T(n) = T(n/2) + O(1) → a=1, b=2, f(n)=1 → Case 2 → O(log n)
  • 快速幂:T(n) = T(n/2) + O(1)O(log n)

3. 均摊分析

某些操作单次最坏复杂度很高,但连续执行 n 次的总复杂度很低。

经典例子:动态数组扩容(如 Swift 的 Array、C++ 的 vector)

swift
// 每次 append 平均 O(1),但偶尔触发扩容 O(n)
var arr: [Int] = []
for i in 0..<n {
    arr.append(i)  // 均摊 O(1)
}
// 总时间 O(n),均摊每次 O(1)

扩容策略通常是容量翻倍,n 次 append 的总拷贝次数为 1+2+4+...+n ≈ 2n,所以均摊 O(1)。

4. 空间复杂度

空间复杂度计算原则:

  • 递归调用栈深度计入空间复杂度
  • 输入数组本身不计入额外空间
  • DP 的滚动数组优化可把 O(n²) 降到 O(n)
python
# 空间 O(n) — 需要额外数组
def merge_sort(arr):
    if len(arr) <= 1: return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    return merge(left, right)

# 空间 O(1) — 原地操作
def reverse(arr):
    i, j = 0, len(arr) - 1
    while i < j:
        arr[i], arr[j] = arr[j], arr[i]
        i += 1; j -= 1

5. 易错点

  • ⚠️ 字符串拼接在循环中可能隐藏 O(n²) 复杂度
  • ⚠️ 递归不记忆化可能导致 O(2ⁿ) 指数爆炸(如朴素递归斐波那契)
  • ⚠️ 排序后再二分,总体是 O(n log n) 而非 O(log n)
  • ⚠️ 哈希表最坏情况是 O(n),但平均 O(1),面试中一般说平均复杂度

推荐刷题清单

题号题名难度关键
169多数元素Easy均摊分析
912排序数组Medium复杂度对比

延伸阅读

基于 VitePress 构建 · 部署于 Cloudflare Pages