同一个算法,输入规模一大,是秒回还是等到天荒地老?大 O 一句话说清。
把滑杆从 8 拖到 256,看同一个输入规模下,不同复杂度要跑多少次运算(假设每秒 1 亿次):
| 复杂度 | 操作次数 | 约耗时 (1e8/s) |
|---|---|---|
| O(1) | 1 | 0 |
| O(log n) | 5 | 0 |
| O(n) | 32 | 0 |
| O(n log n) | 160 | 0 |
| O(n²) | 1024 | 0 |
| O(2ⁿ) | 1.1e10 | 109s |
| 记号 | 名字 | 典型代码 |
|---|---|---|
| O(1) | 常数 | 数组取 a[i]、哈希查一次 |
| O(log n) | 对数 | 二分查找、倍增跳 |
| O(n) | 线性 | 一趟扫描 for(i=0;i<n;i++) |
| O(n log n) | 近线性 | 排序 sort、归并 |
| O(n²) | 平方 | 两层循环各跑 n 次 |
| O(2ⁿ) | 指数 | 枚举所有子集、暴力搜索 |
O(2n)、O(n/2) 都是 O(n)。int a[n][n] 就是 O(n²) 空间,n 一大直接 MLE(超内存)。O(nk)=O(n),不是 O(n²)。O(n) 像一个个人排队:多一个人就多一份时间。O(log n) 像电话本二分查找:规模翻倍只多查一步。O(n²) 像聚会里两两握手:人一多,握手数几乎翻倍地涨。
“规模变大后到底涨多快”是复杂度、也是生物/经济里“规模效应”的共同语言——先估增长,再决定方案可不可行。
for(i=0;i<n;i++) for(j=0;j<n;j++) 时间复杂度是?O(n)、O(2n)、O(n/2)?