Skip to content

Commit 4f9fbe1

Browse files
committed
修正 Latex 公式显示问题
1 parent 5dc0286 commit 4f9fbe1

File tree

86 files changed

+338
-338
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+338
-338
lines changed

Contents/01.Array/02.Array-Sort/02.Array-Selection-Sort.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212

1313
1. 初始状态下,无已排序区间,未排序区间为 $[0, n - 1]$。
1414
2. 第 $1$ 趟选择:
15-
1. 遍历未排序区间 $[0, n - 1]$,使用变量 $min\underline{}i$ 记录区间中值最小的元素位置。
16-
2. 将 $min\underline{}i$ 与下标为 $0$ 处的元素交换位置。如果下标为 $0$ 处元素就是值最小的元素位置,则不用交换。
15+
1. 遍历未排序区间 $[0, n - 1]$,使用变量 $min\underline{\hspace{0.5em}}i$ 记录区间中值最小的元素位置。
16+
2. 将 $min\underline{\hspace{0.5em}}i$ 与下标为 $0$ 处的元素交换位置。如果下标为 $0$ 处元素就是值最小的元素位置,则不用交换。
1717
3. 此时,$[0, 0]$ 为已排序区间,$[1, n - 1]$(总共 $n - 1$ 个元素)为未排序区间。
1818
3. 第 $2$ 趟选择:
19-
1. 遍历未排序区间 $[1, n - 1]$,使用变量 $min\underline{}i$ 记录区间中值最小的元素位置。
20-
2. 将 $min\underline{}i$ 与下标为 $1$ 处的元素交换位置。如果下标为 $1$ 处元素就是值最小的元素位置,则不用交换。
19+
1. 遍历未排序区间 $[1, n - 1]$,使用变量 $min\underline{\hspace{0.5em}}i$ 记录区间中值最小的元素位置。
20+
2. 将 $min\underline{\hspace{0.5em}}i$ 与下标为 $1$ 处的元素交换位置。如果下标为 $1$ 处元素就是值最小的元素位置,则不用交换。
2121
3. 此时,$[0, 1]$ 为已排序区间,$[2, n - 1]$(总共 $n - 2$ 个元素)为未排序区间。
2222
4. 依次类推,对剩余未排序区间重复上述选择过程,直到所有元素都划分到已排序区间,排序结束。
2323

@@ -79,7 +79,7 @@ class Solution:
7979

8080
- **时间复杂度**:$O(n^2)$。排序法所进行的元素之间的比较次数与序列的原始状态无关,时间复杂度总是 $O(n^2)$。
8181
- 这是因为无论序列中元素的初始排列状态如何,第 $i$ 趟排序要找出值最小元素都需要进行 $n − i$ 次元素之间的比较。因此,整个排序过程需要进行的元素之间的比较次数都相同,为 $∑^n_{i=2}(i - 1) = \frac{n(n−1)}{2}$ 次。
82-
- **空间复杂度**:$O(1)$。选择排序算法为原地排序算法,只用到指针变量 $i$、$j$ 以及最小值位置 $min\underline{}i$ 等常数项的变量。
82+
- **空间复杂度**:$O(1)$。选择排序算法为原地排序算法,只用到指针变量 $i$、$j$ 以及最小值位置 $min\underline{\hspace{0.5em}}i$ 等常数项的变量。
8383
- **选择排序适用情况**:选择排序方法在排序过程中需要移动较多次数的元素,并且排序时间效率比较低。因此,选择排序方法比较适合于参加排序序列的数据量较小的情况。选择排序的主要优点是仅需要原地操作无需占用其他空间就可以完成排序,因此在空间复杂度要求较高时,可以考虑选择排序。
8484

8585
- **排序稳定性**:由于值最小元素与未排序区间第 $1$ 个元素的交换动作是在不相邻的元素之间进行的,因此很有可能会改变相等元素的相对顺序,因此,选择排序法是一种 **不稳定排序算法**

Contents/01.Array/02.Array-Sort/05.Array-Merge-Sort.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
假设数组的元素个数为 $n$ 个,则归并排序的算法步骤如下:
1010

1111
1. **分解过程**:先递归地将当前数组平均分成两半,直到子数组长度为 $1$。
12-
1. 找到数组中心位置 $mid$,从中心位置将数组分成左右两个子数组 $left\underline{}nums$、$right\underline{}nums$。
13-
2. 对左右两个子数组 $left\underline{}nums$、$right\underline{}nums$ 分别进行递归分解。
12+
1. 找到数组中心位置 $mid$,从中心位置将数组分成左右两个子数组 $left\underline{\hspace{0.5em}}nums$、$right\underline{\hspace{0.5em}}nums$。
13+
2. 对左右两个子数组 $left\underline{\hspace{0.5em}}nums$、$right\underline{\hspace{0.5em}}nums$ 分别进行递归分解。
1414
3. 最终将数组分解为 $n$ 个长度均为 $1$ 的有序子数组。
1515
2. **归并过程**:从长度为 $1$ 的有序子数组开始,依次将有序数组两两合并,直到合并成一个长度为 $n$ 的有序数组。
1616
1. 使用数组变量 $nums$ 存放合并后的有序数组。
17-
2. 使用两个指针 $left\underline{}i$、$right\underline{}i$ 分别指向两个有序子数组 $left\underline{}nums$、$right\underline{}nums$ 的开始位置。
17+
2. 使用两个指针 $left\underline{\hspace{0.5em}}i$、$right\underline{\hspace{0.5em}}i$ 分别指向两个有序子数组 $left\underline{\hspace{0.5em}}nums$、$right\underline{\hspace{0.5em}}nums$ 的开始位置。
1818
3. 比较两个指针指向的元素,将两个有序子数组中较小元素依次存入到结果数组 $nums$ 中,并将指针移动到下一位置。
1919
4. 重复步骤 $3$,直到某一指针到达子数组末尾。
2020
5. 将另一个子数组中的剩余元素存入到结果数组 $nums$ 中。

Contents/01.Array/02.Array-Sort/08.Array-Counting-Sort.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
77
## 2. 计数排序算法步骤
88

9-
1. **计算排序范围**:遍历数组,找出待排序序列中最大值元素 $nums\underline{}max$ 和最小值元素 $nums\underline{}min$,计算出排序范围为 $nums\underline{}max - nums\underline{}min + 1$。
9+
1. **计算排序范围**:遍历数组,找出待排序序列中最大值元素 $nums\underline{\hspace{0.5em}}max$ 和最小值元素 $nums\underline{\hspace{0.5em}}min$,计算出排序范围为 $nums\underline{\hspace{0.5em}}max - nums\underline{\hspace{0.5em}}min + 1$。
1010
2. **定义计数数组**:定义一个大小为排序范围的计数数组 $counts$,用于统计每个元素的出现次数。其中:
11-
1. 数组的索引值 $num - nums\underline{}min$ 表示元素的值为 $num$。
12-
2. 数组的值 $counts[num - nums\underline{}min]$ 表示元素 $num$ 的出现次数。
11+
1. 数组的索引值 $num - nums\underline{\hspace{0.5em}}min$ 表示元素的值为 $num$。
12+
2. 数组的值 $counts[num - nums\underline{\hspace{0.5em}}min]$ 表示元素 $num$ 的出现次数。
1313

14-
3. **对数组元素进行计数统计**:遍历待排序数组 $nums$,对每个元素在计数数组中进行计数,即将待排序数组中「每个元素值减去最小值」作为索引,将「对计数数组中的值」加 $1$,即令 $counts[num - nums\underline{}min]$ 加 $1$。
15-
4. **生成累积计数数组**:从 $counts$ 中的第 $1$ 个元素开始,每一项累家前一项和。此时 $counts[num - nums\underline{}min]$ 表示值为 $num$ 的元素在排序数组中最后一次出现的位置。
14+
3. **对数组元素进行计数统计**:遍历待排序数组 $nums$,对每个元素在计数数组中进行计数,即将待排序数组中「每个元素值减去最小值」作为索引,将「对计数数组中的值」加 $1$,即令 $counts[num - nums\underline{\hspace{0.5em}}min]$ 加 $1$。
15+
4. **生成累积计数数组**:从 $counts$ 中的第 $1$ 个元素开始,每一项累家前一项和。此时 $counts[num - nums\underline{\hspace{0.5em}}min]$ 表示值为 $num$ 的元素在排序数组中最后一次出现的位置。
1616
5. **逆序填充目标数组**:逆序遍历数组 $nums$,将每个元素 $num$ 填入正确位置。
17-
1. 将其填充到结果数组 $res$ 的索引 $counts[num - nums\underline{}min]$ 处。
17+
1. 将其填充到结果数组 $res$ 的索引 $counts[num - nums\underline{\hspace{0.5em}}min]$ 处。
1818
2. 放入后,令累积计数数组中对应索引减 $1$,从而得到下个元素 $num$ 的放置位置。
1919

2020
我们以 $[3, 0, 4, 2, 5, 1, 3, 1, 4, 5]$ 为例,演示一下计数排序的整个步骤。

Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,10 @@ class Solution:
380380

381381
### 4.1 分离双指针求解步骤
382382

383-
1. 使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向第一个数组的第一个元素,即:$left\underline{}1 = 0$,$left\underline{}2$ 指向第二个数组的第一个元素,即:$left\underline{}2 = 0$。
384-
2. 当满足一定条件时,两个指针同时右移,即 $left\underline{}1 += 1$、$left\underline{}2 += 1$。
385-
3. 当满足另外一定条件时,将 $left\underline{}1$ 指针右移,即 $left\underline{}1 += 1$。
386-
4. 当满足其他一定条件时,将 $left\underline{}2$ 指针右移,即 $left\underline{}2 += 1$。
383+
1. 使用两个指针 $left\underline{\hspace{0.5em}}1$、$left\underline{\hspace{0.5em}}2$。$left\underline{\hspace{0.5em}}1$ 指向第一个数组的第一个元素,即:$left\underline{\hspace{0.5em}}1 = 0$,$left\underline{\hspace{0.5em}}2$ 指向第二个数组的第一个元素,即:$left\underline{\hspace{0.5em}}2 = 0$。
384+
2. 当满足一定条件时,两个指针同时右移,即 $left\underline{\hspace{0.5em}}1 += 1$、$left\underline{\hspace{0.5em}}2 += 1$。
385+
3. 当满足另外一定条件时,将 $left\underline{\hspace{0.5em}}1$ 指针右移,即 $left\underline{\hspace{0.5em}}1 += 1$。
386+
4. 当满足其他一定条件时,将 $left\underline{\hspace{0.5em}}2$ 指针右移,即 $left\underline{\hspace{0.5em}}2 += 1$。
387387
5. 当其中一个数组遍历完时或者满足其他特殊条件时跳出循环体。
388388

389389
### 4.2 分离双指针伪代码模板
@@ -448,10 +448,10 @@ while left_1 < len(nums1) and left_2 < len(nums2):
448448
##### 思路 1:分离双指针
449449

450450
1. 对数组 $nums1$、$nums2$ 先排序。
451-
2. 使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向第一个数组的第一个元素,即:$left\underline{}1 = 0$,$left\underline{}2$ 指向第二个数组的第一个元素,即:$left\underline{}2 = 0$。
452-
3. 如果 $nums1[left\underline{}1] == nums2[left\underline{}2]$,则将其加入答案数组(注意去重),并将 $left\underline{}1$ 和 $left\underline{}2$ 右移。
453-
4. 如果 $nums1[left\underline{}1] < nums2[left\underline{}2]$,则将 $left\underline{}1$ 右移。
454-
5. 如果 $nums1[left\underline{}1] > nums2[left\underline{}2]$,则将 $left\underline{}2$ 右移。
451+
2. 使用两个指针 $left\underline{\hspace{0.5em}}1$、$left\underline{\hspace{0.5em}}2$。$left\underline{\hspace{0.5em}}1$ 指向第一个数组的第一个元素,即:$left\underline{\hspace{0.5em}}1 = 0$,$left\underline{\hspace{0.5em}}2$ 指向第二个数组的第一个元素,即:$left\underline{\hspace{0.5em}}2 = 0$。
452+
3. 如果 $nums1[left\underline{\hspace{0.5em}}1] == nums2[left\underline{\hspace{0.5em}}2]$,则将其加入答案数组(注意去重),并将 $left\underline{\hspace{0.5em}}1$ 和 $left\underline{\hspace{0.5em}}2$ 右移。
453+
4. 如果 $nums1[left\underline{\hspace{0.5em}}1] < nums2[left\underline{\hspace{0.5em}}2]$,则将 $left\underline{\hspace{0.5em}}1$ 右移。
454+
5. 如果 $nums1[left\underline{\hspace{0.5em}}1] > nums2[left\underline{\hspace{0.5em}}2]$,则将 $left\underline{\hspace{0.5em}}2$ 右移。
455455
6. 最后返回答案数组。
456456

457457
##### 思路 1:代码

Contents/01.Array/05.Array-Sliding-Window/01.Array-Sliding-Window.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@
3333

3434
### 3.1 固定长度滑动窗口算法步骤
3535

36-
假设窗口的固定大小为 $window\underline{}size$。
36+
假设窗口的固定大小为 $window\underline{\hspace{0.5em}}size$。
3737

3838
1. 使用两个指针 $left$、$right$。初始时,$left$、$right$ 都指向序列的第一个元素,即:$left = 0$,$right = 0$,区间 $[left, right]$ 被称为一个「窗口」。
39-
2. 当窗口未达到 $window\underline{}size$ 大小时,不断移动 $right$,先将数组前 $window\underline{}size$ 个元素填入窗口中,即 `window.append(nums[right])`
40-
2. 当窗口达到 $window\underline{}size$ 大小时,即满足 `right - left + 1 >= window_size` 时,判断窗口内的连续元素是否满足题目限定的条件。
39+
2. 当窗口未达到 $window\underline{\hspace{0.5em}}size$ 大小时,不断移动 $right$,先将数组前 $window\underline{\hspace{0.5em}}size$ 个元素填入窗口中,即 `window.append(nums[right])`
40+
2. 当窗口达到 $window\underline{\hspace{0.5em}}size$ 大小时,即满足 `right - left + 1 >= window_size` 时,判断窗口内的连续元素是否满足题目限定的条件。
4141
1. 如果满足,再根据要求更新最优解。
42-
2. 然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{}size$。
42+
2. 然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{\hspace{0.5em}}size$。
4343
3. 向右移动 $right$,将元素填入窗口中,即 `window.append(nums[right])`
4444
4. 重复 $2 \sim 4$ 步,直到 $right$ 到达数组末尾。
4545

@@ -107,7 +107,7 @@ while right < len(nums):
107107

108108
这道题目是典型的固定窗口大小的滑动窗口题目。窗口大小为 $k$。具体做法如下:
109109

110-
1. $ans$ 用来维护答案数目。$window\underline{}sum$ 用来维护窗口中元素的和。
110+
1. $ans$ 用来维护答案数目。$window\underline{\hspace{0.5em}}sum$ 用来维护窗口中元素的和。
111111
2. $left$ 、$right$ 都指向序列的第一个元素,即:$left = 0$,$right = 0$。
112112
3. 向右移动 $right$,先将 $k$ 个元素填入窗口中,即 `window_sum += arr[right]`
113113
4. 当窗口元素个数为 $k$ 时,即满足 `right - left + 1 >= k` 时,判断窗口内的元素和平均值是否大于等于阈值 $threshold$。
@@ -301,8 +301,8 @@ class Solution:
301301
用滑动窗口来记录连续子数组的和,设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口中的和刚好大于等于 $target$。
302302

303303
1. 一开始,$left$、$right$ 都指向 $0$。
304-
2. 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{}sum$ 中。
305-
3. 如果 $window\underline{}sum \ge target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{}sum < target$。
304+
2. 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{\hspace{0.5em}}sum$ 中。
305+
3. 如果 $window\underline{\hspace{0.5em}}sum \ge target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{\hspace{0.5em}}sum < target$。
306306
4. 然后继续右移 $right$,直到 $right \ge len(nums)$ 结束。
307307
5. 输出窗口和的最小值作为答案。
308308

@@ -374,10 +374,10 @@ class Solution:
374374

375375
##### 思路 1:滑动窗口(不定长度)
376376

377-
1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内所有数的乘积 $window\underline{}product$ 都小于 $k$。使用 $window\underline{}product$ 记录窗口中的乘积值,使用 $count$ 记录符合要求的子数组个数。
377+
1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内所有数的乘积 $window\underline{\hspace{0.5em}}product$ 都小于 $k$。使用 $window\underline{\hspace{0.5em}}product$ 记录窗口中的乘积值,使用 $count$ 记录符合要求的子数组个数。
378378
2. 一开始,$left$、$right$ 都指向 $0$。
379-
3. 向右移动 $right$,将最右侧元素加入当前子数组乘积 $window\underline{}product$ 中。
380-
4. 如果 $window\underline{}product \ge k$,则不断右移 $left$,缩小滑动窗口长度,并更新当前乘积值 $window\underline{}product$ 直到 $window\underline{}product < k$。
379+
3. 向右移动 $right$,将最右侧元素加入当前子数组乘积 $window\underline{\hspace{0.5em}}product$ 中。
380+
4. 如果 $window\underline{\hspace{0.5em}}product \ge k$,则不断右移 $left$,缩小滑动窗口长度,并更新当前乘积值 $window\underline{\hspace{0.5em}}product$ 直到 $window\underline{\hspace{0.5em}}product < k$。
381381
5. 记录累积答案个数加 $1$,继续右移 $right$,直到 $right \ge len(nums)$ 结束。
382382
6. 输出累积答案个数。
383383

Contents/03.Stack/02.Monotone-Stack/01.Monotone-Stack.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,14 @@ def monotoneDecreasingStack(nums):
173173

174174
第二种思路是使用单调递增栈。因为 $nums1$ 是 $nums2$ 的子集,所以我们可以先遍历一遍 $nums2$,并构造单调递增栈,求出 $nums2$ 中每个元素右侧下一个更大的元素。然后将其存储到哈希表中。然后再遍历一遍 $nums1$,从哈希表中取出对应结果,存放到答案数组中。这种解法的时间复杂度是 $O(n)$。具体做法如下:
175175

176-
- 使用数组 $res$ 存放答案。使用 $stack$ 表示单调递增栈。使用哈希表 $num\underline{}map$ 用于存储 $nums2$ 中下一个比当前元素大的数值,映射关系为 **当前元素值:下一个比当前元素大的数值**
176+
- 使用数组 $res$ 存放答案。使用 $stack$ 表示单调递增栈。使用哈希表 $num\underline{\hspace{0.5em}}map$ 用于存储 $nums2$ 中下一个比当前元素大的数值,映射关系为 **当前元素值:下一个比当前元素大的数值**
177177
- 遍历数组 $nums2$,对于当前元素:
178178
- 如果当前元素值较小,则直接让当前元素值入栈。
179179
- 如果当前元素值较大,则一直出栈,直到当前元素值小于栈顶元素。
180-
- 出栈时,出栈元素是第一个大于当前元素值的元素。则将其映射到 $num\underline{}map$ 中。
180+
- 出栈时,出栈元素是第一个大于当前元素值的元素。则将其映射到 $num\underline{\hspace{0.5em}}map$ 中。
181181

182182
- 遍历完数组 $nums2$,建立好所有元素下一个更大元素的映射关系之后,再遍历数组 $nums1$。
183-
- 从 $num\underline{}map$ 中取出对应的值,将其加入到答案数组中。
183+
- 从 $num\underline{\hspace{0.5em}}map$ 中取出对应的值,将其加入到答案数组中。
184184
- 最终输出答案数组 $res$。
185185

186186
#### 4.1.4 代码

Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
### 2.1 Rabin Karp 算法整体步骤
1010

1111
1. 对于给定的文本串 $T$ 与模式串 $p$,求出文本串 $T$ 的长度为 $n$,模式串 $p$ 的长度为 $m$。
12-
2. 通过滚动哈希算法求出模式串 $p$ 的哈希值 $hash\underline{}p$。
13-
3. 再通过滚动哈希算法对文本串 $T$ 中 $n - m + 1$ 个子串分别求哈希值 $hash\underline{}t$。
12+
2. 通过滚动哈希算法求出模式串 $p$ 的哈希值 $hash\underline{\hspace{0.5em}}p$。
13+
3. 再通过滚动哈希算法对文本串 $T$ 中 $n - m + 1$ 个子串分别求哈希值 $hash\underline{\hspace{0.5em}}t$。
1414
4. 然后逐个与模式串的哈希值比较大小。
15-
1. 如果当前子串的哈希值 $hash\underline{}t$ 与模式串的哈希值 $hash\underline{}p$ 不同,则说明两者不匹配,则继续向后匹配。
16-
2. 如果当前子串的哈希值 $hash\underline{}t$ 与模式串的哈希值 $hash\underline{}p$ 相等,则验证当前子串和模式串的每个字符是否真的相等(避免哈希冲突)。
15+
1. 如果当前子串的哈希值 $hash\underline{\hspace{0.5em}}t$ 与模式串的哈希值 $hash\underline{\hspace{0.5em}}p$ 不同,则说明两者不匹配,则继续向后匹配。
16+
2. 如果当前子串的哈希值 $hash\underline{\hspace{0.5em}}t$ 与模式串的哈希值 $hash\underline{\hspace{0.5em}}p$ 相等,则验证当前子串和模式串的每个字符是否真的相等(避免哈希冲突)。
1717
1. 如果当前子串和模式串的每个字符相等,则说明当前子串和模式串匹配。
1818
2. 如果当前子串和模式串的每个字符不相等,则说明两者不匹配,继续向后匹配。
1919
5. 比较到末尾,如果仍未成功匹配,则说明文本串 $T$ 中不包含模式串 $p$,方法返回 $-1$。

0 commit comments

Comments
 (0)