This commit is contained in:
krahets
2023-08-20 13:37:08 +08:00
parent 2e27ad1680
commit 44a8568356
32 changed files with 140 additions and 130 deletions
@@ -644,7 +644,7 @@ $T(n)$ 是一次函数,说明时间的增长趋势是线性的,因此其时
根据定义,确定 $f(n)$ 之后,我们便可得到时间复杂度 $O(f(n))$ 。那么如何确定渐近上界 $f(n)$ 呢?总体分为两步:首先统计操作数量,然后判断渐近上界。
### 第一步:统计操作数量
### 1.   第一步:统计操作数量
针对代码,逐行从上到下计算即可。然而,由于上述 $c \cdot f(n)$ 中的常数项 $c$ 可以取任意大小,**因此操作数量 $T(n)$ 中的各种系数、常数项都可以被忽略**。根据此原则,可以总结出以下计数简化技巧:
@@ -875,7 +875,7 @@ $$
}
```
### 第二步:判断渐近上界
### 2.   第二步:判断渐近上界
**时间复杂度由多项式 $T(n)$ 中最高阶的项来决定**。这是因为在 $n$ 趋于无穷大时,最高阶的项将发挥主导作用,其他项的影响都可以被忽略。
@@ -913,7 +913,7 @@ $$
部分示例代码需要一些预备知识,包括数组、递归等。如果你遇到不理解的部分,可以在学习完后面章节后再回顾。现阶段,请先专注于理解时间复杂度的含义和推算方法。
### 常数阶 $O(1)$
### 1.   常数阶 $O(1)$
常数阶的操作数量与输入数据大小 $n$ 无关,即不随着 $n$ 的变化而变化。
@@ -1082,7 +1082,7 @@ $$
}
```
### 线性阶 $O(n)$
### 2.   线性阶 $O(n)$
线性阶的操作数量相对于输入数据大小以线性级别增长。线性阶通常出现在单层循环中。
@@ -1404,7 +1404,7 @@ $$
值得注意的是,**数据大小 $n$ 需根据输入数据的类型来具体确定**。比如在第一个示例中,变量 $n$ 为输入数据大小;在第二个示例中,数组长度 $n$ 为数据大小。
### 平方阶 $O(n^2)$
### 3.   平方阶 $O(n^2)$
平方阶的操作数量相对于输入数据大小以平方级别增长。平方阶通常出现在嵌套循环中,外层循环和内层循环都为 $O(n)$ ,因此总体为 $O(n^2)$ 。
@@ -1881,7 +1881,7 @@ $$
}
```
### 指数阶 $O(2^n)$
### 4.   指数阶 $O(2^n)$
生物学的“细胞分裂”是指数阶增长的典型例子:初始状态为 $1$ 个细胞,分裂一轮后变为 $2$ 个,分裂两轮后变为 $4$ 个,以此类推,分裂 $n$ 轮后有 $2^n$ 个细胞。
@@ -2246,7 +2246,7 @@ $$
指数阶增长非常迅速,在穷举法(暴力搜索、回溯等)中比较常见。对于数据规模较大的问题,指数阶是不可接受的,通常需要使用「动态规划」或「贪心」等算法来解决。
### 对数阶 $O(\log n)$
### 5.   对数阶 $O(\log n)$
与指数阶相反,对数阶反映了“每轮缩减到一半”的情况。设输入数据大小为 $n$ ,由于每轮缩减到一半,因此循环次数是 $\log_2 n$ ,即 $2^n$ 的反函数。
@@ -2556,7 +2556,7 @@ $$
对数阶常出现于基于「分治」的算法中,体现了“一分为多”和“化繁为简”的算法思想。它增长缓慢,是理想的时间复杂度,仅次于常数阶。
### 线性对数阶 $O(n \log n)$
### 6.   线性对数阶 $O(n \log n)$
线性对数阶常出现于嵌套循环中,两层循环的时间复杂度分别为 $O(\log n)$ 和 $O(n)$ 。
@@ -2748,7 +2748,7 @@ $$
<p align="center"> 图:线性对数阶的时间复杂度 </p>
### 阶乘阶 $O(n!)$
### 7. &nbsp; 阶乘阶 $O(n!)$
阶乘阶对应数学上的“全排列”问题。给定 $n$ 个互不重复的元素,求其所有可能的排列方案,方案数量为: