From 4f9fbe1fcd3916102fbfefa7f08549d4667abcc2 Mon Sep 17 00:00:00 2001 From: ITCharge Date: Mon, 6 May 2024 14:02:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20Latex=20=E5=85=AC=E5=BC=8F?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../02.Array-Sort/02.Array-Selection-Sort.md | 10 +++---- .../02.Array-Sort/05.Array-Merge-Sort.md | 6 ++-- .../02.Array-Sort/08.Array-Counting-Sort.md | 12 ++++---- .../01.Array-Two-Pointers.md | 16 +++++----- .../01.Array-Sliding-Window.md | 20 ++++++------- .../02.Monotone-Stack/01.Monotone-Stack.md | 6 ++-- .../02.String-Rabin-Karp.md | 8 ++--- .../01.Graph-Basic/02.Graph-Structure.md | 6 ++-- .../02.Graph-Traversal/03.Graph-BFS.md | 10 +++---- .../01.Greedy-Algorithm.md | 12 ++++---- .../02.Memoization/01.Memoization.md | 26 ++++++++-------- .../04.Knapsack-Problem-04.md | 14 ++++----- .../06.Tree-DP/01.Tree-DP.md | 14 ++++----- .../07.State-DP/01.State-DP.md | 14 ++++----- ...36\346\226\207\345\255\220\344\270\262.md" | 2 +- ...51\351\230\265\347\275\256\351\233\266.md" | 4 +-- ...345\244\215\345\205\203\347\264\240 II.md" | 4 +-- ...47\350\267\257\345\276\204\345\222\214.md" | 6 ++-- .... \345\205\213\351\232\206\345\233\276.md" | 8 ++--- ...04\345\255\220\346\225\260\347\273\204.md" | 4 +-- ...40\347\232\204\344\270\252\346\225\260.md" | 6 ++-- ...04\347\232\204\344\272\244\351\233\206.md" | 8 ++--- ...N \344\275\215\346\225\260\345\255\227.md" | 4 +-- ...15\345\274\202\344\275\215\350\257\215.md" | 6 ++-- ...51\345\255\227\347\254\246\344\270\262.md" | 6 ++-- .... \344\270\200\345\222\214\351\233\266.md" | 4 +-- ...43\344\270\255\344\275\215\346\225\260.md" | 28 ++++++++--------- ...347\232\204\344\270\252\346\225\260 II.md" | 4 +-- .... \347\233\256\346\240\207\345\222\214.md" | 30 +++++++++---------- ...16\347\232\204\346\216\222\345\210\227.md" | 4 +-- ...04\345\255\220\346\225\260\347\273\204.md" | 18 +++++------ ...62\347\232\204\346\216\222\345\210\227.md" | 8 ++--- ...\345\271\263\345\235\207\346\225\260 I.md" | 2 +- ...22\345\242\236\345\272\217\345\210\227.md" | 4 +-- ...64\347\272\270\346\213\274\350\257\215.md" | 6 ++-- ...00\345\244\247\351\235\242\347\247\257.md" | 2 +- ...11\347\232\204\345\255\220\351\233\206.md" | 4 +-- ...04\345\255\220\346\225\260\347\273\204.md" | 6 ++-- .... \346\211\223\347\240\226\345\235\227.md" | 6 ++-- ...01\347\232\204\350\241\214\346\225\260.md" | 2 +- ...01\347\232\204\345\215\225\350\257\215.md" | 2 +- ...04\345\255\227\347\254\246\344\270\262.md" | 12 ++++---- ...55\345\255\220\346\225\260\347\273\204.md" | 14 ++++----- ...33\345\210\266\351\227\264\350\267\235.md" | 4 +-- ...04\350\241\250\351\235\242\347\247\257.md" | 8 ++--- ...E \350\277\255\344\273\243\345\231\250.md" | 6 ++-- ...22\345\272\217\346\225\260\347\273\204.md" | 26 ++++++++-------- ...77\346\214\211\351\224\256\345\205\245.md" | 16 +++++----- ...73\350\275\254\346\254\241\346\225\260.md" | 8 ++--- ...04\346\243\213\345\255\220\346\225\260.md" | 2 +- ...47\232\204\344\270\252\346\225\260 III.md" | 6 ++-- ...347\232\204\351\207\215\351\207\217 II.md" | 4 +-- ...46\345\272\227\350\200\201\346\235\277.md" | 4 +-- ...345\210\206\347\263\226\346\236\234 II.md" | 6 ++-- ...40\347\202\271\346\210\220\346\236\227.md" | 8 ++--- ...\346\211\200\346\234\211\347\232\204 1.md" | 8 ++--- ...05\345\205\203\347\264\240\345\222\214.md" | 4 +-- ...41\345\210\222\350\257\204\344\274\260.md" | 2 +- ...46\344\270\262\347\233\270\347\255\211.md" | 4 +-- ...32\350\256\256\346\227\245\347\250\213.md" | 8 ++--- ...21\347\232\204\347\233\264\345\276\204.md" | 8 ++--- ...45\346\211\276\345\205\203\347\264\240.md" | 2 +- ...04\346\225\260\347\273\204\345\222\214.md" | 4 +-- ...23\345\215\260\345\215\225\350\257\215.md" | 2 +- ...17\346\255\245\351\252\244\346\225\260.md" | 4 +-- ...47\345\255\246\347\224\237\346\225\260.md" | 10 +++---- ...00\345\244\247\347\202\271\346\225\260.md" | 12 ++++---- ...00\345\244\247\346\225\260\347\233\256.md" | 4 +-- ...77\345\255\220\346\225\260\347\273\204.md" | 4 +-- ...75\344\270\211\345\205\203\347\273\204.md" | 6 ++-- ...71\346\256\212\344\275\215\347\275\256.md" | 4 +-- ...60\347\233\256\346\234\200\345\244\247.md" | 4 +-- ...40\351\231\244\346\254\241\346\225\260.md" | 6 ++-- ...17\346\223\215\344\275\234\346\225\260.md" | 10 +++---- ...04\344\272\247\346\200\273\351\207\217.md" | 6 ++-- ...00\345\244\247\345\276\227\345\210\206.md" | 2 +- ...45\345\255\220\346\216\222\345\272\217.md" | 4 +-- ...26\345\200\274\344\271\213\345\222\214.md" | 2 +- ...47\350\257\204\345\210\206\345\222\214.md" | 4 +-- ...55\351\227\264\344\275\215\347\275\256.md" | 8 ++--- ...06\347\232\204\346\225\260\347\233\256.md" | 4 +-- ...00\345\244\247\344\270\216\345\222\214.md" | 6 ++-- ...00\351\225\277\350\267\257\345\276\204.md" | 8 ++--- ...14\347\232\204\345\267\256\345\200\274.md" | 16 +++++----- ...64\346\225\260\346\225\260\347\233\256.md" | 14 ++++----- ...04\351\200\206\345\272\217\345\257\271.md" | 10 +++---- 86 files changed, 338 insertions(+), 338 deletions(-) diff --git a/Contents/01.Array/02.Array-Sort/02.Array-Selection-Sort.md b/Contents/01.Array/02.Array-Sort/02.Array-Selection-Sort.md index ed31b9a6..5bd13d0b 100644 --- a/Contents/01.Array/02.Array-Sort/02.Array-Selection-Sort.md +++ b/Contents/01.Array/02.Array-Sort/02.Array-Selection-Sort.md @@ -12,12 +12,12 @@ 1. 初始状态下,无已排序区间,未排序区间为 $[0, n - 1]$。 2. 第 $1$ 趟选择: - 1. 遍历未排序区间 $[0, n - 1]$,使用变量 $min\underline{}i$ 记录区间中值最小的元素位置。 - 2. 将 $min\underline{}i$ 与下标为 $0$ 处的元素交换位置。如果下标为 $0$ 处元素就是值最小的元素位置,则不用交换。 + 1. 遍历未排序区间 $[0, n - 1]$,使用变量 $min\underline{\hspace{0.5em}}i$ 记录区间中值最小的元素位置。 + 2. 将 $min\underline{\hspace{0.5em}}i$ 与下标为 $0$ 处的元素交换位置。如果下标为 $0$ 处元素就是值最小的元素位置,则不用交换。 3. 此时,$[0, 0]$ 为已排序区间,$[1, n - 1]$(总共 $n - 1$ 个元素)为未排序区间。 3. 第 $2$ 趟选择: - 1. 遍历未排序区间 $[1, n - 1]$,使用变量 $min\underline{}i$ 记录区间中值最小的元素位置。 - 2. 将 $min\underline{}i$ 与下标为 $1$ 处的元素交换位置。如果下标为 $1$ 处元素就是值最小的元素位置,则不用交换。 + 1. 遍历未排序区间 $[1, n - 1]$,使用变量 $min\underline{\hspace{0.5em}}i$ 记录区间中值最小的元素位置。 + 2. 将 $min\underline{\hspace{0.5em}}i$ 与下标为 $1$ 处的元素交换位置。如果下标为 $1$ 处元素就是值最小的元素位置,则不用交换。 3. 此时,$[0, 1]$ 为已排序区间,$[2, n - 1]$(总共 $n - 2$ 个元素)为未排序区间。 4. 依次类推,对剩余未排序区间重复上述选择过程,直到所有元素都划分到已排序区间,排序结束。 @@ -79,7 +79,7 @@ class Solution: - **时间复杂度**:$O(n^2)$。排序法所进行的元素之间的比较次数与序列的原始状态无关,时间复杂度总是 $O(n^2)$。 - 这是因为无论序列中元素的初始排列状态如何,第 $i$ 趟排序要找出值最小元素都需要进行 $n − i$ 次元素之间的比较。因此,整个排序过程需要进行的元素之间的比较次数都相同,为 $∑^n_{i=2}(i - 1) = \frac{n(n−1)}{2}$ 次。 -- **空间复杂度**:$O(1)$。选择排序算法为原地排序算法,只用到指针变量 $i$、$j$ 以及最小值位置 $min\underline{}i$ 等常数项的变量。 +- **空间复杂度**:$O(1)$。选择排序算法为原地排序算法,只用到指针变量 $i$、$j$ 以及最小值位置 $min\underline{\hspace{0.5em}}i$ 等常数项的变量。 - **选择排序适用情况**:选择排序方法在排序过程中需要移动较多次数的元素,并且排序时间效率比较低。因此,选择排序方法比较适合于参加排序序列的数据量较小的情况。选择排序的主要优点是仅需要原地操作无需占用其他空间就可以完成排序,因此在空间复杂度要求较高时,可以考虑选择排序。 - **排序稳定性**:由于值最小元素与未排序区间第 $1$ 个元素的交换动作是在不相邻的元素之间进行的,因此很有可能会改变相等元素的相对顺序,因此,选择排序法是一种 **不稳定排序算法**。 diff --git a/Contents/01.Array/02.Array-Sort/05.Array-Merge-Sort.md b/Contents/01.Array/02.Array-Sort/05.Array-Merge-Sort.md index b9f989c1..af223533 100644 --- a/Contents/01.Array/02.Array-Sort/05.Array-Merge-Sort.md +++ b/Contents/01.Array/02.Array-Sort/05.Array-Merge-Sort.md @@ -9,12 +9,12 @@ 假设数组的元素个数为 $n$ 个,则归并排序的算法步骤如下: 1. **分解过程**:先递归地将当前数组平均分成两半,直到子数组长度为 $1$。 - 1. 找到数组中心位置 $mid$,从中心位置将数组分成左右两个子数组 $left\underline{}nums$、$right\underline{}nums$。 - 2. 对左右两个子数组 $left\underline{}nums$、$right\underline{}nums$ 分别进行递归分解。 + 1. 找到数组中心位置 $mid$,从中心位置将数组分成左右两个子数组 $left\underline{\hspace{0.5em}}nums$、$right\underline{\hspace{0.5em}}nums$。 + 2. 对左右两个子数组 $left\underline{\hspace{0.5em}}nums$、$right\underline{\hspace{0.5em}}nums$ 分别进行递归分解。 3. 最终将数组分解为 $n$ 个长度均为 $1$ 的有序子数组。 2. **归并过程**:从长度为 $1$ 的有序子数组开始,依次将有序数组两两合并,直到合并成一个长度为 $n$ 的有序数组。 1. 使用数组变量 $nums$ 存放合并后的有序数组。 - 2. 使用两个指针 $left\underline{}i$、$right\underline{}i$ 分别指向两个有序子数组 $left\underline{}nums$、$right\underline{}nums$ 的开始位置。 + 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$ 的开始位置。 3. 比较两个指针指向的元素,将两个有序子数组中较小元素依次存入到结果数组 $nums$ 中,并将指针移动到下一位置。 4. 重复步骤 $3$,直到某一指针到达子数组末尾。 5. 将另一个子数组中的剩余元素存入到结果数组 $nums$ 中。 diff --git a/Contents/01.Array/02.Array-Sort/08.Array-Counting-Sort.md b/Contents/01.Array/02.Array-Sort/08.Array-Counting-Sort.md index 29c05587..05e4c2e1 100644 --- a/Contents/01.Array/02.Array-Sort/08.Array-Counting-Sort.md +++ b/Contents/01.Array/02.Array-Sort/08.Array-Counting-Sort.md @@ -6,15 +6,15 @@ ## 2. 计数排序算法步骤 -1. **计算排序范围**:遍历数组,找出待排序序列中最大值元素 $nums\underline{}max$ 和最小值元素 $nums\underline{}min$,计算出排序范围为 $nums\underline{}max - nums\underline{}min + 1$。 +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$。 2. **定义计数数组**:定义一个大小为排序范围的计数数组 $counts$,用于统计每个元素的出现次数。其中: - 1. 数组的索引值 $num - nums\underline{}min$ 表示元素的值为 $num$。 - 2. 数组的值 $counts[num - nums\underline{}min]$ 表示元素 $num$ 的出现次数。 + 1. 数组的索引值 $num - nums\underline{\hspace{0.5em}}min$ 表示元素的值为 $num$。 + 2. 数组的值 $counts[num - nums\underline{\hspace{0.5em}}min]$ 表示元素 $num$ 的出现次数。 -3. **对数组元素进行计数统计**:遍历待排序数组 $nums$,对每个元素在计数数组中进行计数,即将待排序数组中「每个元素值减去最小值」作为索引,将「对计数数组中的值」加 $1$,即令 $counts[num - nums\underline{}min]$ 加 $1$。 -4. **生成累积计数数组**:从 $counts$ 中的第 $1$ 个元素开始,每一项累家前一项和。此时 $counts[num - nums\underline{}min]$ 表示值为 $num$ 的元素在排序数组中最后一次出现的位置。 +3. **对数组元素进行计数统计**:遍历待排序数组 $nums$,对每个元素在计数数组中进行计数,即将待排序数组中「每个元素值减去最小值」作为索引,将「对计数数组中的值」加 $1$,即令 $counts[num - nums\underline{\hspace{0.5em}}min]$ 加 $1$。 +4. **生成累积计数数组**:从 $counts$ 中的第 $1$ 个元素开始,每一项累家前一项和。此时 $counts[num - nums\underline{\hspace{0.5em}}min]$ 表示值为 $num$ 的元素在排序数组中最后一次出现的位置。 5. **逆序填充目标数组**:逆序遍历数组 $nums$,将每个元素 $num$ 填入正确位置。 - 1. 将其填充到结果数组 $res$ 的索引 $counts[num - nums\underline{}min]$ 处。 + 1. 将其填充到结果数组 $res$ 的索引 $counts[num - nums\underline{\hspace{0.5em}}min]$ 处。 2. 放入后,令累积计数数组中对应索引减 $1$,从而得到下个元素 $num$ 的放置位置。 我们以 $[3, 0, 4, 2, 5, 1, 3, 1, 4, 5]$ 为例,演示一下计数排序的整个步骤。 diff --git a/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md b/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md index d8068ee6..2f2d18c7 100644 --- a/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md +++ b/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md @@ -380,10 +380,10 @@ class Solution: ### 4.1 分离双指针求解步骤 -1. 使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向第一个数组的第一个元素,即:$left\underline{}1 = 0$,$left\underline{}2$ 指向第二个数组的第一个元素,即:$left\underline{}2 = 0$。 -2. 当满足一定条件时,两个指针同时右移,即 $left\underline{}1 += 1$、$left\underline{}2 += 1$。 -3. 当满足另外一定条件时,将 $left\underline{}1$ 指针右移,即 $left\underline{}1 += 1$。 -4. 当满足其他一定条件时,将 $left\underline{}2$ 指针右移,即 $left\underline{}2 += 1$。 +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$。 +2. 当满足一定条件时,两个指针同时右移,即 $left\underline{\hspace{0.5em}}1 += 1$、$left\underline{\hspace{0.5em}}2 += 1$。 +3. 当满足另外一定条件时,将 $left\underline{\hspace{0.5em}}1$ 指针右移,即 $left\underline{\hspace{0.5em}}1 += 1$。 +4. 当满足其他一定条件时,将 $left\underline{\hspace{0.5em}}2$ 指针右移,即 $left\underline{\hspace{0.5em}}2 += 1$。 5. 当其中一个数组遍历完时或者满足其他特殊条件时跳出循环体。 ### 4.2 分离双指针伪代码模板 @@ -448,10 +448,10 @@ while left_1 < len(nums1) and left_2 < len(nums2): ##### 思路 1:分离双指针 1. 对数组 $nums1$、$nums2$ 先排序。 -2. 使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向第一个数组的第一个元素,即:$left\underline{}1 = 0$,$left\underline{}2$ 指向第二个数组的第一个元素,即:$left\underline{}2 = 0$。 -3. 如果 $nums1[left\underline{}1] == nums2[left\underline{}2]$,则将其加入答案数组(注意去重),并将 $left\underline{}1$ 和 $left\underline{}2$ 右移。 -4. 如果 $nums1[left\underline{}1] < nums2[left\underline{}2]$,则将 $left\underline{}1$ 右移。 -5. 如果 $nums1[left\underline{}1] > nums2[left\underline{}2]$,则将 $left\underline{}2$ 右移。 +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$。 +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$ 右移。 +4. 如果 $nums1[left\underline{\hspace{0.5em}}1] < nums2[left\underline{\hspace{0.5em}}2]$,则将 $left\underline{\hspace{0.5em}}1$ 右移。 +5. 如果 $nums1[left\underline{\hspace{0.5em}}1] > nums2[left\underline{\hspace{0.5em}}2]$,则将 $left\underline{\hspace{0.5em}}2$ 右移。 6. 最后返回答案数组。 ##### 思路 1:代码 diff --git a/Contents/01.Array/05.Array-Sliding-Window/01.Array-Sliding-Window.md b/Contents/01.Array/05.Array-Sliding-Window/01.Array-Sliding-Window.md index 5b2ec775..56b7a0db 100644 --- a/Contents/01.Array/05.Array-Sliding-Window/01.Array-Sliding-Window.md +++ b/Contents/01.Array/05.Array-Sliding-Window/01.Array-Sliding-Window.md @@ -33,13 +33,13 @@ ### 3.1 固定长度滑动窗口算法步骤 -假设窗口的固定大小为 $window\underline{}size$。 +假设窗口的固定大小为 $window\underline{\hspace{0.5em}}size$。 1. 使用两个指针 $left$、$right$。初始时,$left$、$right$ 都指向序列的第一个元素,即:$left = 0$,$right = 0$,区间 $[left, right]$ 被称为一个「窗口」。 -2. 当窗口未达到 $window\underline{}size$ 大小时,不断移动 $right$,先将数组前 $window\underline{}size$ 个元素填入窗口中,即 `window.append(nums[right])`。 -2. 当窗口达到 $window\underline{}size$ 大小时,即满足 `right - left + 1 >= window_size` 时,判断窗口内的连续元素是否满足题目限定的条件。 +2. 当窗口未达到 $window\underline{\hspace{0.5em}}size$ 大小时,不断移动 $right$,先将数组前 $window\underline{\hspace{0.5em}}size$ 个元素填入窗口中,即 `window.append(nums[right])`。 +2. 当窗口达到 $window\underline{\hspace{0.5em}}size$ 大小时,即满足 `right - left + 1 >= window_size` 时,判断窗口内的连续元素是否满足题目限定的条件。 1. 如果满足,再根据要求更新最优解。 - 2. 然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{}size$。 + 2. 然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{\hspace{0.5em}}size$。 3. 向右移动 $right$,将元素填入窗口中,即 `window.append(nums[right])`。 4. 重复 $2 \sim 4$ 步,直到 $right$ 到达数组末尾。 @@ -107,7 +107,7 @@ while right < len(nums): 这道题目是典型的固定窗口大小的滑动窗口题目。窗口大小为 $k$。具体做法如下: -1. $ans$ 用来维护答案数目。$window\underline{}sum$ 用来维护窗口中元素的和。 +1. $ans$ 用来维护答案数目。$window\underline{\hspace{0.5em}}sum$ 用来维护窗口中元素的和。 2. $left$ 、$right$ 都指向序列的第一个元素,即:$left = 0$,$right = 0$。 3. 向右移动 $right$,先将 $k$ 个元素填入窗口中,即 `window_sum += arr[right]`。 4. 当窗口元素个数为 $k$ 时,即满足 `right - left + 1 >= k` 时,判断窗口内的元素和平均值是否大于等于阈值 $threshold$。 @@ -301,8 +301,8 @@ class Solution: 用滑动窗口来记录连续子数组的和,设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口中的和刚好大于等于 $target$。 1. 一开始,$left$、$right$ 都指向 $0$。 -2. 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{}sum$ 中。 -3. 如果 $window\underline{}sum \ge target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{}sum < target$。 +2. 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{\hspace{0.5em}}sum$ 中。 +3. 如果 $window\underline{\hspace{0.5em}}sum \ge target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{\hspace{0.5em}}sum < target$。 4. 然后继续右移 $right$,直到 $right \ge len(nums)$ 结束。 5. 输出窗口和的最小值作为答案。 @@ -374,10 +374,10 @@ class Solution: ##### 思路 1:滑动窗口(不定长度) -1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内所有数的乘积 $window\underline{}product$ 都小于 $k$。使用 $window\underline{}product$ 记录窗口中的乘积值,使用 $count$ 记录符合要求的子数组个数。 +1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内所有数的乘积 $window\underline{\hspace{0.5em}}product$ 都小于 $k$。使用 $window\underline{\hspace{0.5em}}product$ 记录窗口中的乘积值,使用 $count$ 记录符合要求的子数组个数。 2. 一开始,$left$、$right$ 都指向 $0$。 -3. 向右移动 $right$,将最右侧元素加入当前子数组乘积 $window\underline{}product$ 中。 -4. 如果 $window\underline{}product \ge k$,则不断右移 $left$,缩小滑动窗口长度,并更新当前乘积值 $window\underline{}product$ 直到 $window\underline{}product < k$。 +3. 向右移动 $right$,将最右侧元素加入当前子数组乘积 $window\underline{\hspace{0.5em}}product$ 中。 +4. 如果 $window\underline{\hspace{0.5em}}product \ge k$,则不断右移 $left$,缩小滑动窗口长度,并更新当前乘积值 $window\underline{\hspace{0.5em}}product$ 直到 $window\underline{\hspace{0.5em}}product < k$。 5. 记录累积答案个数加 $1$,继续右移 $right$,直到 $right \ge len(nums)$ 结束。 6. 输出累积答案个数。 diff --git a/Contents/03.Stack/02.Monotone-Stack/01.Monotone-Stack.md b/Contents/03.Stack/02.Monotone-Stack/01.Monotone-Stack.md index 495c0d97..70699198 100644 --- a/Contents/03.Stack/02.Monotone-Stack/01.Monotone-Stack.md +++ b/Contents/03.Stack/02.Monotone-Stack/01.Monotone-Stack.md @@ -173,14 +173,14 @@ def monotoneDecreasingStack(nums): 第二种思路是使用单调递增栈。因为 $nums1$ 是 $nums2$ 的子集,所以我们可以先遍历一遍 $nums2$,并构造单调递增栈,求出 $nums2$ 中每个元素右侧下一个更大的元素。然后将其存储到哈希表中。然后再遍历一遍 $nums1$,从哈希表中取出对应结果,存放到答案数组中。这种解法的时间复杂度是 $O(n)$。具体做法如下: -- 使用数组 $res$ 存放答案。使用 $stack$ 表示单调递增栈。使用哈希表 $num\underline{}map$ 用于存储 $nums2$ 中下一个比当前元素大的数值,映射关系为 **当前元素值:下一个比当前元素大的数值**。 +- 使用数组 $res$ 存放答案。使用 $stack$ 表示单调递增栈。使用哈希表 $num\underline{\hspace{0.5em}}map$ 用于存储 $nums2$ 中下一个比当前元素大的数值,映射关系为 **当前元素值:下一个比当前元素大的数值**。 - 遍历数组 $nums2$,对于当前元素: - 如果当前元素值较小,则直接让当前元素值入栈。 - 如果当前元素值较大,则一直出栈,直到当前元素值小于栈顶元素。 - - 出栈时,出栈元素是第一个大于当前元素值的元素。则将其映射到 $num\underline{}map$ 中。 + - 出栈时,出栈元素是第一个大于当前元素值的元素。则将其映射到 $num\underline{\hspace{0.5em}}map$ 中。 - 遍历完数组 $nums2$,建立好所有元素下一个更大元素的映射关系之后,再遍历数组 $nums1$。 -- 从 $num\underline{}map$ 中取出对应的值,将其加入到答案数组中。 +- 从 $num\underline{\hspace{0.5em}}map$ 中取出对应的值,将其加入到答案数组中。 - 最终输出答案数组 $res$。 #### 4.1.4 代码 diff --git a/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md b/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md index 40671189..9adc6642 100644 --- a/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md +++ b/Contents/06.String/02.String-Single-Pattern-Matching/02.String-Rabin-Karp.md @@ -9,11 +9,11 @@ ### 2.1 Rabin Karp 算法整体步骤 1. 对于给定的文本串 $T$ 与模式串 $p$,求出文本串 $T$ 的长度为 $n$,模式串 $p$ 的长度为 $m$。 -2. 通过滚动哈希算法求出模式串 $p$ 的哈希值 $hash\underline{}p$。 -3. 再通过滚动哈希算法对文本串 $T$ 中 $n - m + 1$ 个子串分别求哈希值 $hash\underline{}t$。 +2. 通过滚动哈希算法求出模式串 $p$ 的哈希值 $hash\underline{\hspace{0.5em}}p$。 +3. 再通过滚动哈希算法对文本串 $T$ 中 $n - m + 1$ 个子串分别求哈希值 $hash\underline{\hspace{0.5em}}t$。 4. 然后逐个与模式串的哈希值比较大小。 - 1. 如果当前子串的哈希值 $hash\underline{}t$ 与模式串的哈希值 $hash\underline{}p$ 不同,则说明两者不匹配,则继续向后匹配。 - 2. 如果当前子串的哈希值 $hash\underline{}t$ 与模式串的哈希值 $hash\underline{}p$ 相等,则验证当前子串和模式串的每个字符是否真的相等(避免哈希冲突)。 + 1. 如果当前子串的哈希值 $hash\underline{\hspace{0.5em}}t$ 与模式串的哈希值 $hash\underline{\hspace{0.5em}}p$ 不同,则说明两者不匹配,则继续向后匹配。 + 2. 如果当前子串的哈希值 $hash\underline{\hspace{0.5em}}t$ 与模式串的哈希值 $hash\underline{\hspace{0.5em}}p$ 相等,则验证当前子串和模式串的每个字符是否真的相等(避免哈希冲突)。 1. 如果当前子串和模式串的每个字符相等,则说明当前子串和模式串匹配。 2. 如果当前子串和模式串的每个字符不相等,则说明两者不匹配,继续向后匹配。 5. 比较到末尾,如果仍未成功匹配,则说明文本串 $T$ 中不包含模式串 $p$,方法返回 $-1$。 diff --git a/Contents/08.Graph/01.Graph-Basic/02.Graph-Structure.md b/Contents/08.Graph/01.Graph-Basic/02.Graph-Structure.md index ec12ab5d..7a0512ea 100644 --- a/Contents/08.Graph/01.Graph-Basic/02.Graph-Structure.md +++ b/Contents/08.Graph/01.Graph-Basic/02.Graph-Structure.md @@ -10,10 +10,10 @@ #### 1.1.1 邻接矩阵的原理描述 -> **邻接矩阵(Adjacency Matrix)**:使用一个二维数组 $adj\underline{}matrix$ 来存储顶点之间的邻接关系。 +> **邻接矩阵(Adjacency Matrix)**:使用一个二维数组 $adj\underline{\hspace{0.5em}}matrix$ 来存储顶点之间的邻接关系。 > -> - 对于无权图来说,如果 $adj\underline{}matrix[i][j]$ 为 $1$,则说明顶点 $v_i$ 到 $v_j$ 存在边,如果 $adj\underline{}matrix[i][j]$ 为 $0$,则说明顶点 $v_i$ 到 $v_j$ 不存在边。 -> - 对于带权图来说,如果 $adj\underline{}matrix[i][j]$ 为 $w$,并且 $w \ne \infty$(即 `w != float('inf')`),则说明顶点 $v_i$ 到 $v_j$ 的权值为 $w$。如果 $adj\underline{}matrix[i][j]$ 为 $\infty$(即 `float('inf')`),则说明顶点 $v_i$ 到 $v_j$ 不存在边。 +> - 对于无权图来说,如果 $adj\underline{\hspace{0.5em}}matrix[i][j]$ 为 $1$,则说明顶点 $v_i$ 到 $v_j$ 存在边,如果 $adj\underline{\hspace{0.5em}}matrix[i][j]$ 为 $0$,则说明顶点 $v_i$ 到 $v_j$ 不存在边。 +> - 对于带权图来说,如果 $adj\underline{\hspace{0.5em}}matrix[i][j]$ 为 $w$,并且 $w \ne \infty$(即 `w != float('inf')`),则说明顶点 $v_i$ 到 $v_j$ 的权值为 $w$。如果 $adj\underline{\hspace{0.5em}}matrix[i][j]$ 为 $\infty$(即 `float('inf')`),则说明顶点 $v_i$ 到 $v_j$ 不存在边。 在下面的示意图中,左侧是一个无向图,右侧则是该无向图对应的邻接矩阵结构。 diff --git a/Contents/08.Graph/02.Graph-Traversal/03.Graph-BFS.md b/Contents/08.Graph/02.Graph-Traversal/03.Graph-BFS.md index af18e135..85410ed6 100644 --- a/Contents/08.Graph/02.Graph-Traversal/03.Graph-BFS.md +++ b/Contents/08.Graph/02.Graph-Traversal/03.Graph-BFS.md @@ -146,10 +146,10 @@ Solution().bfs(graph, "0") 1. 使用哈希表 $visited$ 来存储原图中被访问过的节点和克隆图中对应节点,键值对为「原图被访问过的节点:克隆图中对应节点」。使用队列 $queue$ 存放节点。 2. 根据起始节点 $node$,创建一个新的节点,并将其添加到哈希表 $visited$ 中,即 `visited[node] = Node(node.val, [])`。然后将起始节点放入队列中,即 `queue.append(node)`。 -3. 从队列中取出第一个节点 $node\underline{}u$。访问节点 $node\underline{}u$。 -4. 遍历节点 $node\underline{}u$ 的所有未访问邻接节点 $node\underline{}v$(节点 $node\underline{}v$ 不在 $visited$ 中)。 -5. 根据节点 $node\underline{}v$ 创建一个新的节点,并将其添加到哈希表 $visited$ 中,即 `visited[node_v] = Node(node_v.val, [])`。 -6. 然后将节点 $node\underline{}v$ 放入队列 $queue$ 中,即 `queue.append(node_v)`。 +3. 从队列中取出第一个节点 $node\underline{\hspace{0.5em}}u$。访问节点 $node\underline{\hspace{0.5em}}u$。 +4. 遍历节点 $node\underline{\hspace{0.5em}}u$ 的所有未访问邻接节点 $node\underline{\hspace{0.5em}}v$(节点 $node\underline{\hspace{0.5em}}v$ 不在 $visited$ 中)。 +5. 根据节点 $node\underline{\hspace{0.5em}}v$ 创建一个新的节点,并将其添加到哈希表 $visited$ 中,即 `visited[node_v] = Node(node_v.val, [])`。 +6. 然后将节点 $node\underline{\hspace{0.5em}}v$ 放入队列 $queue$ 中,即 `queue.append(node_v)`。 7. 重复步骤 $3 \sim 6$,直到队列 $queue$ 为空。 8. 广度优先搜索结束,返回起始节点的克隆节点(即 $visited[node]$)。 @@ -227,7 +227,7 @@ class Solution: 1. 使用 $ans$ 记录最大岛屿面积。 2. 遍历二维数组的每一个元素,对于每个值为 $1$ 的元素: - 1. 将该元素置为 $0$。并使用队列 $queue$ 存储该节点位置。使用 $temp\underline{}ans$ 记录当前岛屿面积。 + 1. 将该元素置为 $0$。并使用队列 $queue$ 存储该节点位置。使用 $temp\underline{\hspace{0.5em}}ans$ 记录当前岛屿面积。 2. 然后从队列 $queue$ 中取出第一个节点位置 $(i, j)$。遍历该节点位置上、下、左、右四个方向上的相邻节点。并将其置为 $0$(避免重复搜索)。并将其加入到队列中。并累加当前岛屿面积,即 `temp_ans += 1`。 3. 不断重复上一步骤,直到队列 $queue$ 为空。 4. 更新当前最大岛屿面积,即 `ans = max(ans, temp_ans)`。 diff --git a/Contents/09.Algorithm-Base/05.Greedy-Algorithm/01.Greedy-Algorithm.md b/Contents/09.Algorithm-Base/05.Greedy-Algorithm/01.Greedy-Algorithm.md index b0c1447d..8d46a631 100644 --- a/Contents/09.Algorithm-Base/05.Greedy-Algorithm/01.Greedy-Algorithm.md +++ b/Contents/09.Algorithm-Base/05.Greedy-Algorithm/01.Greedy-Algorithm.md @@ -120,10 +120,10 @@ 使用贪心算法的代码解决步骤描述如下: -1. 对数组 $g$、$s$ 进行从小到大排序,使用变量 $index\underline{}g$ 和 $index\underline{}s$ 分别指向 $g$、$s$ 初始位置,使用变量 $res$ 保存结果,初始化为 $0$。 -2. 对比每个元素 $g[index\underline{}g]$ 和 $s[index\underline{}s]$: - 1. 如果 $g[index\underline{}g] \le s[index\underline{}s]$,说明当前饼干满足当前孩子胃口,则答案数量加 $1$,并且向右移动 $index\underline{}g$ 和 $index\underline{}s$。 - 2. 如果 $g[index\underline{}g] > s[index\underline{}s]$,说明当前饼干无法满足当前孩子胃口,则向右移动 $index_s$,判断下一块饼干是否可以满足当前孩子胃口。 +1. 对数组 $g$、$s$ 进行从小到大排序,使用变量 $index\underline{\hspace{0.5em}}g$ 和 $index\underline{\hspace{0.5em}}s$ 分别指向 $g$、$s$ 初始位置,使用变量 $res$ 保存结果,初始化为 $0$。 +2. 对比每个元素 $g[index\underline{\hspace{0.5em}}g]$ 和 $s[index\underline{\hspace{0.5em}}s]$: + 1. 如果 $g[index\underline{\hspace{0.5em}}g] \le s[index\underline{\hspace{0.5em}}s]$,说明当前饼干满足当前孩子胃口,则答案数量加 $1$,并且向右移动 $index\underline{\hspace{0.5em}}g$ 和 $index\underline{\hspace{0.5em}}s$。 + 2. 如果 $g[index\underline{\hspace{0.5em}}g] > s[index\underline{\hspace{0.5em}}s]$,说明当前饼干无法满足当前孩子胃口,则向右移动 $index_s$,判断下一块饼干是否可以满足当前孩子胃口。 3. 遍历完输出答案 $res$。 ##### 思路 1:代码 @@ -203,9 +203,9 @@ class Solution: 使用贪心算法的代码解决步骤描述如下: -1. 将区间集合按照结束坐标升序排列,然后维护两个变量,一个是当前不重叠区间的结束时间 $end\underline{}pos$,另一个是不重叠区间的个数 $count$。初始情况下,结束坐标 $end\underline{}pos$ 为第一个区间的结束坐标,$count$ 为 $1$。 +1. 将区间集合按照结束坐标升序排列,然后维护两个变量,一个是当前不重叠区间的结束时间 $end\underline{\hspace{0.5em}}pos$,另一个是不重叠区间的个数 $count$。初始情况下,结束坐标 $end\underline{\hspace{0.5em}}pos$ 为第一个区间的结束坐标,$count$ 为 $1$。 2. 依次遍历每段区间。对于每段区间:$intervals[i]$: - 1. 如果 $end\underline{}pos \le intervals[i][0]$,即 $end\underline{}pos$ 小于等于区间起始位置,则说明出现了不重叠区间,令不重叠区间数 $count$ 加 $1$,$end\underline{}pos$ 更新为新区间的结束位置。 + 1. 如果 $end\underline{\hspace{0.5em}}pos \le intervals[i][0]$,即 $end\underline{\hspace{0.5em}}pos$ 小于等于区间起始位置,则说明出现了不重叠区间,令不重叠区间数 $count$ 加 $1$,$end\underline{\hspace{0.5em}}pos$ 更新为新区间的结束位置。 3. 最终返回「总区间个数 - 不重叠区间的最多个数」即 $len(intervals) - count$ 作为答案。 ##### 思路 1:代码 diff --git a/Contents/10.Dynamic-Programming/02.Memoization/01.Memoization.md b/Contents/10.Dynamic-Programming/02.Memoization/01.Memoization.md index 989c46f3..ef46933e 100644 --- a/Contents/10.Dynamic-Programming/02.Memoization/01.Memoization.md +++ b/Contents/10.Dynamic-Programming/02.Memoization/01.Memoization.md @@ -123,11 +123,11 @@ class Solution: 1. 定义从位置 $0$、和为 $0$ 开始,到达数组尾部位置为止,和为 $target$ 的方案数为 `dfs(0, 0)`。 2. 下面从位置 $0$、和为 $0$ 开始,以深度优先搜索遍历每个位置。 3. 如果当前位置 $i$ 到达最后一个位置 $size$: - 1. 如果和 $cur\underline{}sum$ 等于目标和 $target$,则返回方案数 $1$。 - 2. 如果和 $cur\underline{}sum$ 不等于目标和 $target$,则返回方案数 $0$。 -4. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum - nums[i]$ 的方案数。 -5. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum + nums[i]$ 的方案数。 -6. 将 4 ~ 5 两个方案数加起来就是当前位置 $i$、和为 $cur\underline{}sum$ 的方案数,返回该方案数。 + 1. 如果和 $cur\underline{\hspace{0.5em}}sum$ 等于目标和 $target$,则返回方案数 $1$。 + 2. 如果和 $cur\underline{\hspace{0.5em}}sum$ 不等于目标和 $target$,则返回方案数 $0$。 +4. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum - nums[i]$ 的方案数。 +5. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum + nums[i]$ 的方案数。 +6. 将 4 ~ 5 两个方案数加起来就是当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 的方案数,返回该方案数。 7. 最终方案数为 `dfs(0, 0)`,将其作为答案返回即可。 ##### 思路 1:代码 @@ -158,18 +158,18 @@ class Solution: 在思路 1 中我们单独使用深度优先搜索对每位数字进行 `+` 或者 `-` 的方法超时了。所以我们考虑使用记忆化搜索的方式,避免进行重复搜索。 -这里我们使用哈希表 $table$ 记录遍历过的位置 $i$ 及所得到的的当前和$cur\underline{}sum$ 下的方案数,来避免重复搜索。具体步骤如下: +这里我们使用哈希表 $table$ 记录遍历过的位置 $i$ 及所得到的的当前和$cur\underline{\hspace{0.5em}}sum$ 下的方案数,来避免重复搜索。具体步骤如下: 1. 定义从位置 $0$、和为 $0$ 开始,到达数组尾部位置为止,和为 $target$ 的方案数为 `dfs(0, 0)`。 2. 下面从位置 $0$、和为 $0$ 开始,以深度优先搜索遍历每个位置。 3. 如果当前位置 $i$ 遍历完所有位置: - 1. 如果和 $cur\underline{}sum$ 等于目标和 $target$,则返回方案数 $1$。 - 2. 如果和 $cur\underline{}sum$ 不等于目标和 $target$,则返回方案数 $0$。 -4. 如果当前位置 $i$、和为 $cur\underline{}sum$ 之前记录过(即使用 $table$ 记录过对应方案数),则返回该方案数。 -5. 如果当前位置 $i$、和为 $cur\underline{}sum$ 之前没有记录过,则: - 1. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum - nums[i]$ 的方案数。 - 2. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum + nums[i]$ 的方案数。 - 3. 将上述两个方案数加起来就是当前位置 $i$、和为 $cur\underline{}sum$ 的方案数,将其记录到哈希表 $table$ 中,并返回该方案数。 + 1. 如果和 $cur\underline{\hspace{0.5em}}sum$ 等于目标和 $target$,则返回方案数 $1$。 + 2. 如果和 $cur\underline{\hspace{0.5em}}sum$ 不等于目标和 $target$,则返回方案数 $0$。 +4. 如果当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 之前记录过(即使用 $table$ 记录过对应方案数),则返回该方案数。 +5. 如果当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 之前没有记录过,则: + 1. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum - nums[i]$ 的方案数。 + 2. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum + nums[i]$ 的方案数。 + 3. 将上述两个方案数加起来就是当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 的方案数,将其记录到哈希表 $table$ 中,并返回该方案数。 6. 最终方案数为 `dfs(0, 0)`,将其作为答案返回即可。 ##### 思路 2:代码 diff --git a/Contents/10.Dynamic-Programming/04.Knapsack-Problem/04.Knapsack-Problem-04.md b/Contents/10.Dynamic-Programming/04.Knapsack-Problem/04.Knapsack-Problem-04.md index 778b9228..85f87c23 100644 --- a/Contents/10.Dynamic-Programming/04.Knapsack-Problem/04.Knapsack-Problem-04.md +++ b/Contents/10.Dynamic-Programming/04.Knapsack-Problem/04.Knapsack-Problem-04.md @@ -80,7 +80,7 @@ class Solution: ## 6. 分组背包问题 -> **分组背包问题**:有 $n$ 组物品和一个最多能装重量为 $W$ 的背包,第 $i$ 组物品的件数为 $group\underline{}count[i]$,第 $i$ 组的第 $j$ 个物品重量为 $weight[i][j]$,价值为 $value[i][j]$。每组物品中最多只能选择 $1$ 件物品装入背包。请问在总重量不超过背包载重上限的情况下,能装入背包的最大价值是多少? +> **分组背包问题**:有 $n$ 组物品和一个最多能装重量为 $W$ 的背包,第 $i$ 组物品的件数为 $group\underline{\hspace{0.5em}}count[i]$,第 $i$ 组的第 $j$ 个物品重量为 $weight[i][j]$,价值为 $value[i][j]$。每组物品中最多只能选择 $1$ 件物品装入背包。请问在总重量不超过背包载重上限的情况下,能装入背包的最大价值是多少? ![](https://qcdn.itcharge.cn/images/20230329095729.png) @@ -100,17 +100,17 @@ class Solution: ###### 3. 状态转移方程 -由于我们可以不选择 $i - 1$ 组物品中的任何物品,也可以从第 $i - 1$ 组物品的第 $0 \sim group\underline{}count[i - 1] - 1$ 件物品中随意选择 $1$ 件物品,所以状态 $dp[i][w]$ 可能从以下方案中选择最大值: +由于我们可以不选择 $i - 1$ 组物品中的任何物品,也可以从第 $i - 1$ 组物品的第 $0 \sim group\underline{\hspace{0.5em}}count[i - 1] - 1$ 件物品中随意选择 $1$ 件物品,所以状态 $dp[i][w]$ 可能从以下方案中选择最大值: 1. 不选择第 $i - 1$ 组中的任何物品:可以获得的最大价值为 $dp[i - 1][w]$。 2. 选择第 $i - 1$ 组物品中第 $0$ 件:可以获得的最大价值为 $dp[i - 1][w - weight[i - 1][0]] + value[i - 1][0]$。 3. 选择第 $i - 1$ 组物品中第 $1$ 件:可以获得的最大价值为 $dp[i - 1][w - weight[i - 1][1]] + value[i - 1][1]$。 4. …… -5. 选择第 $i - 1$ 组物品中最后 $1$ 件:假设 $k = group\underline{}count[i - 1] - 1$,则可以获得的最大价值为 $dp[i - 1][w - weight[i - 1][k]] + value[i - 1][k]$。 +5. 选择第 $i - 1$ 组物品中最后 $1$ 件:假设 $k = group\underline{\hspace{0.5em}}count[i - 1] - 1$,则可以获得的最大价值为 $dp[i - 1][w - weight[i - 1][k]] + value[i - 1][k]$。 则状态转移方程为: -$dp[i][w] = max \lbrace dp[i - 1][w], dp[i - 1][w - weight[i - 1][k]] + value[i - 1][k] \rbrace , \quad 0 \le k \le group\underline{}count[i - 1]$ +$dp[i][w] = max \lbrace dp[i - 1][w], dp[i - 1][w - weight[i - 1][k]] + value[i - 1][k] \rbrace , \quad 0 \le k \le group\underline{\hspace{0.5em}}count[i - 1]$ ###### 4. 初始条件 @@ -144,7 +144,7 @@ class Solution: #### 思路 1:复杂度分析 -- **时间复杂度**:$O(n \times W \times C)$,其中 $n$ 为物品分组数量,$W$ 为背包的载重上限,$C$ 是每组物品的数量。因为 $n \times C = \sum group\underline{}count[i]$,所以时间复杂度也可以写成 $O(W \times \sum group\underline{}count[i])$。 +- **时间复杂度**:$O(n \times W \times C)$,其中 $n$ 为物品分组数量,$W$ 为背包的载重上限,$C$ 是每组物品的数量。因为 $n \times C = \sum group\underline{\hspace{0.5em}}count[i]$,所以时间复杂度也可以写成 $O(W \times \sum group\underline{\hspace{0.5em}}count[i])$。 - **空间复杂度**:$O(n \times W)$。 ### 6.2 分组背包问题滚动数组优化 @@ -161,7 +161,7 @@ class Solution: ###### 3. 状态转移方程 -$dp[w] = max \lbrace dp[w], \quad dp[w - weight[i - 1][k]] + value[i - 1][k] \rbrace , \quad 0 \le k \le group\underline{}count[i - 1]$ +$dp[w] = max \lbrace dp[w], \quad dp[w - weight[i - 1][k]] + value[i - 1][k] \rbrace , \quad 0 \le k \le group\underline{\hspace{0.5em}}count[i - 1]$ ###### 4. 初始条件 @@ -195,7 +195,7 @@ class Solution: #### 思路 2:复杂度分析 -- **时间复杂度**:$O(n \times W \times C)$,其中 $n$ 为物品分组数量,$W$ 为背包的载重上限,$C$ 是每组物品的数量。因为 $n \times C = \sum group\underline{}count[i]$,所以时间复杂度也可以写成 $O(W \times \sum group\underline{}count[i])$。 +- **时间复杂度**:$O(n \times W \times C)$,其中 $n$ 为物品分组数量,$W$ 为背包的载重上限,$C$ 是每组物品的数量。因为 $n \times C = \sum group\underline{\hspace{0.5em}}count[i]$,所以时间复杂度也可以写成 $O(W \times \sum group\underline{\hspace{0.5em}}count[i])$。 - **空间复杂度**:$O(W)$。 ## 7. 二维费用背包问题 diff --git a/Contents/10.Dynamic-Programming/06.Tree-DP/01.Tree-DP.md b/Contents/10.Dynamic-Programming/06.Tree-DP/01.Tree-DP.md index 1302e6ad..9dd5983a 100644 --- a/Contents/10.Dynamic-Programming/06.Tree-DP/01.Tree-DP.md +++ b/Contents/10.Dynamic-Programming/06.Tree-DP/01.Tree-DP.md @@ -96,9 +96,9 @@ 在递归时,我们先计算左右子节点的最大贡献值,再更新维护当前最大路径和变量。最终 $ans$ 即为答案。具体步骤如下: 1. 如果根节点 $root$ 为空,则返回 $0$。 -2. 递归计算左子树的最大贡献值为 $left\underline{}max$。 -3. 递归计算右子树的最大贡献值为 $right\underline{}max$。 -4. 更新维护最大路径和变量,即 $self.ans = max \lbrace self.ans, \quad left\underline{}max + right\underline{}max + node.val \rbrace$。 +2. 递归计算左子树的最大贡献值为 $left\underline{\hspace{0.5em}}max$。 +3. 递归计算右子树的最大贡献值为 $right\underline{\hspace{0.5em}}max$。 +4. 更新维护最大路径和变量,即 $self.ans = max \lbrace self.ans, \quad left\underline{\hspace{0.5em}}max + right\underline{\hspace{0.5em}}max + node.val \rbrace$。 5. 返回以当前节点为根节点,并且经过该节点的最大贡献值。即返回 **当前节点值 + 左右子节点提供的最大贡献值中较大的一个**。 6. 最终 $self.ans$ 即为答案。 @@ -195,11 +195,11 @@ class Solution: 即:**最长路径长度 = max(某子树中的最长路径长度 + 另一子树中的最长路径长度 + 1,某个子树中的最长路径长度)**。 -对此,我们可以使用深度优先搜索递归遍历 $u$ 的所有相邻节点 $v$,并在递归遍历的同时,维护一个全局最大路径和变量 $ans$,以及当前节点 $u$ 的最大路径长度变量 $u\underline{}len$。 +对此,我们可以使用深度优先搜索递归遍历 $u$ 的所有相邻节点 $v$,并在递归遍历的同时,维护一个全局最大路径和变量 $ans$,以及当前节点 $u$ 的最大路径长度变量 $u\underline{\hspace{0.5em}}len$。 -1. 先计算出从相邻节点 $v$ 出发的最长路径长度 $v\underline{}len$。 -2. 更新维护全局最长路径长度为 $self.ans = max(self.ans, \quad u\underline{}len + v\underline{}len + 1)$。 -3. 更新维护当前节点 $u$ 的最长路径长度为 $u\underline{}len = max(u\underline{}len, \quad v\underline{}len + 1)$。 +1. 先计算出从相邻节点 $v$ 出发的最长路径长度 $v\underline{\hspace{0.5em}}len$。 +2. 更新维护全局最长路径长度为 $self.ans = max(self.ans, \quad u\underline{\hspace{0.5em}}len + v\underline{\hspace{0.5em}}len + 1)$。 +3. 更新维护当前节点 $u$ 的最长路径长度为 $u\underline{\hspace{0.5em}}len = max(u\underline{\hspace{0.5em}}len, \quad v\underline{\hspace{0.5em}}len + 1)$。 因为题目限定了「相邻节点字符不同」,所以在更新全局最长路径长度和当前节点 $u$ 的最长路径长度时,我们需要判断一下节点 $u$ 与相邻节点 $v$ 的字符是否相同,只有在字符不同的条件下,才能够更新维护。 diff --git a/Contents/10.Dynamic-Programming/07.State-DP/01.State-DP.md b/Contents/10.Dynamic-Programming/07.State-DP/01.State-DP.md index b5eaad57..4282362d 100644 --- a/Contents/10.Dynamic-Programming/07.State-DP/01.State-DP.md +++ b/Contents/10.Dynamic-Programming/07.State-DP/01.State-DP.md @@ -16,22 +16,22 @@ | 集合 S 中元素位置 | 5 | 4 | 3 | 2 | 1 | | :---------------- | :--: | :--: | :--: | :--: | :--: | -| 二进位对应值 | 1 | 1 | 1 | 1 | 1 | | 对应选取状态 | 选取 | 选取 | 选取 | 选取 | 选取 | +| 二进位对应值 | 1 | 1 | 1 | 1 | 1 | 再比如二进制数 $10101_{(2)}$ 就表示选取集合的第 $1$ 位、第 $3$ 位、第 $5$ 位元素,也就是集合 $\lbrace 5, 3, 1 \rbrace$。如下表所示: | 集合 S 中元素位置 | 5 | 4 | 3 | 2 | 1 | | :---------------- | :--: | :----: | :--: | :----: | :--: | -| 二进位对应值 | 1 | 0 | 1 | 0 | 1 | | 对应选取状态 | 选取 | 未选取 | 选取 | 未选取 | 选取 | +| 二进位对应值 | 1 | 0 | 1 | 0 | 1 | 再比如二进制数 $01001_{(2)}$ 就表示选取集合的第 $1$ 位、第 $4$ 位元素,也就是集合 $\lbrace 4, 1 \rbrace$。如下标所示: | 集合 S 中元素位置 | 5 | 4 | 3 | 2 | 1 | | :---------------- | :----: | :--: | :----: | :----: | :--: | -| 二进位对应值 | 0 | 1 | 0 | 0 | 1 | | 对应选取状态 | 未选取 | 选取 | 未选取 | 未选取 | 选取 | +| 二进位对应值 | 0 | 1 | 0 | 0 | 1 | 通过上面的例子我们可以得到启发:对于长度为 $5$ 的集合 $S$ 来说,我们只需要从 $00000 \sim 11111$ 枚举一次(对应十进制为 $0 \sim 2^5 - 1$)即可得到长度为 $5$ 的集合 $S$ 的所有子集。 @@ -175,7 +175,7 @@ 举个例子 $nums2 = \lbrace 1, 2, 3, 4 \rbrace$,$state = (1001)_2$,表示选择了第 $1$ 个元素和第 $4$ 个元素,也就是 $1$、$4$。那么 $state$ 只能从 $(1000)_2$ 和 $(0001)_2$ 这两个状态转移而来,我们只需要枚举这两种状态,并求出转移过来的异或值之和最小值。 -即状态转移方程为:$dp[state] = min(dp[state], \quad dp[state \oplus (1 \text{ <}\text{< } i)] + (nums1[i] \oplus nums2[one\underline{}cnt - 1]))$,其中 $state$ 第 $i$ 位一定为 $1$,$one\underline{}cnt$ 为 $state$ 中 $1$ 的个数。 +即状态转移方程为:$dp[state] = min(dp[state], \quad dp[state \oplus (1 \text{ <}\text{< } i)] + (nums1[i] \oplus nums2[one\underline{\hspace{0.5em}}cnt - 1]))$,其中 $state$ 第 $i$ 位一定为 $1$,$one\underline{\hspace{0.5em}}cnt$ 为 $state$ 中 $1$ 的个数。 ###### 4. 初始条件 @@ -281,12 +281,12 @@ class Solution: 对于当前状态 $dp[state]$,肯定是从比 $state$ 少选一个元素的状态中递推而来。我们可以枚举少选一个元素的状态,找到可以获得的最大与和,赋值给 $dp[state]$。 -即状态转移方程为:$dp[state] = min(dp[state], dp[state \oplus (1 \text{ <}\text{< } i)] + (i // 2 + 1) \text{ \& } nums[one\underline{}cnt - 1])$,其中: +即状态转移方程为:$dp[state] = min(dp[state], dp[state \oplus (1 \text{ <}\text{< } i)] + (i // 2 + 1) \text{ \& } nums[one\underline{\hspace{0.5em}}cnt - 1])$,其中: 1. $state$ 第 $i$ 位一定为 $1$。 2. $state \oplus (1 \text{ <}\text{< } i)$ 为比 $state$ 少选一个元素的状态。 3. $i // 2 + 1$ 为篮子对应编号 -4. $nums[one\underline{}cnt - 1]$ 为当前正在考虑的数组元素。 +4. $nums[one\underline{\hspace{0.5em}}cnt - 1]$ 为当前正在考虑的数组元素。 ###### 4. 初始条件 @@ -296,7 +296,7 @@ class Solution: 根据我们之前定义的状态,$dp[state]$ 表示为:将前 $count(state)$ 个整数放到篮子里,并且每个篮子中的整数放取情况为 $state$ 时,可以获得的最大与和。所以最终结果为 $max(dp)$。 -> 注意:当 $one\underline{}cnt > len(nums)$ 时,无法通过递推得到 $dp[state]$,需要跳过。 +> 注意:当 $one\underline{\hspace{0.5em}}cnt > len(nums)$ 时,无法通过递推得到 $dp[state]$,需要跳过。 ##### 思路 1:代码 diff --git "a/Solutions/0005. \346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.md" "b/Solutions/0005. \346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.md" index 522120ce..ecf59ea1 100644 --- "a/Solutions/0005. \346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.md" +++ "b/Solutions/0005. \346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.md" @@ -59,7 +59,7 @@ ###### 5. 最终结果 -根据我们之前定义的状态,$dp[i][j]$ 表示为:字符串 $s$ 在区间 $[i, j]$ 范围内是否是一个回文串。当判断完 $s[i: j]$ 是否为回文串时,同时判断并更新最长回文子串的起始位置 $max\underline{}start$ 和最大长度 $max\underline{}len$。则最终结果为 $s[max\underline{}start, max\underline{}start + max\underline{}len]$。 +根据我们之前定义的状态,$dp[i][j]$ 表示为:字符串 $s$ 在区间 $[i, j]$ 范围内是否是一个回文串。当判断完 $s[i: j]$ 是否为回文串时,同时判断并更新最长回文子串的起始位置 $max\underline{\hspace{0.5em}}start$ 和最大长度 $max\underline{\hspace{0.5em}}len$。则最终结果为 $s[max\underline{\hspace{0.5em}}start, max\underline{\hspace{0.5em}}start + max\underline{\hspace{0.5em}}len]$。 ### 思路 1:代码 diff --git "a/Solutions/0073. \347\237\251\351\230\265\347\275\256\351\233\266.md" "b/Solutions/0073. \347\237\251\351\230\265\347\275\256\351\233\266.md" index aa27ca84..6b70f58f 100644 --- "a/Solutions/0073. \347\237\251\351\230\265\347\275\256\351\233\266.md" +++ "b/Solutions/0073. \347\237\251\351\230\265\347\275\256\351\233\266.md" @@ -53,11 +53,11 @@ 考虑使用数组原本的元素进行记录出现 $0$ 的情况。 -1. 设定两个变量 $flag\underline{}row0$、$flag\underline{}col0$ 来标记第一行、第一列是否出现了 $0$。 +1. 设定两个变量 $flag\underline{\hspace{0.5em}}row0$、$flag\underline{\hspace{0.5em}}col0$ 来标记第一行、第一列是否出现了 $0$。 2. 接下来我们使用数组第一行、第一列来标记 $0$ 的情况。 3. 对数组除第一行、第一列之外的每个元素进行遍历,如果某个元素出现 $0$ 了,则使用数组的第一行、第一列对应位置来存储 $0$ 的标记。 4. 再对数组除第一行、第一列之外的每个元素进行遍历,通过对第一行、第一列的标记 $0$ 情况,进行置为 $0$ 的操作。 -5. 最后再根据 $flag\underline{}row0$、$flag\underline{}col0$ 的标记情况,对第一行、第一列进行置为 $0$ 的操作。 +5. 最后再根据 $flag\underline{\hspace{0.5em}}row0$、$flag\underline{\hspace{0.5em}}col0$ 的标记情况,对第一行、第一列进行置为 $0$ 的操作。 ### 思路 1:代码 diff --git "a/Solutions/0082. \345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240 II.md" "b/Solutions/0082. \345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240 II.md" index 13d9b780..a0e2b2d1 100644 --- "a/Solutions/0082. \345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240 II.md" +++ "b/Solutions/0082. \345\210\240\351\231\244\346\216\222\345\272\217\351\223\276\350\241\250\344\270\255\347\232\204\351\207\215\345\244\215\345\205\203\347\264\240 II.md" @@ -34,12 +34,12 @@ 这道题的题意是需要保留所有不同数字,而重复出现的所有数字都要删除。因为给定的链表是升序排列的,所以我们要删除的重复元素在链表中的位置是连续的。所以我们可以对链表进行一次遍历,然后将连续的重复元素从链表中删除即可。具体步骤如下: -- 先使用哑节点 $dummy\underline{}head$ 构造一个指向 $head$ 的指针,使得可以防止从 $head$ 开始就是重复元素。 +- 先使用哑节点 $dummy\underline{\hspace{0.5em}}head$ 构造一个指向 $head$ 的指针,使得可以防止从 $head$ 开始就是重复元素。 - 然后使用指针 $cur$ 表示链表中当前元素,从 $head$ 开始遍历。 - 当指针 $cur$ 的下一个元素和下下一个元素存在时: - 如果下一个元素值和下下一个元素值相同,则我们使用指针 $temp$ 保存下一个元素,并使用 $temp$ 向后遍历,跳过所有重复元素,然后令 $cur$ 的下一个元素指向 $temp$ 的下一个元素,继续向后遍历。 - 如果下一个元素值和下下一个元素值不同,则令 $cur$ 向右移动一位,继续向后遍历。 -- 当指针 $cur$ 的下一个元素或者下下一个元素不存在时,说明已经遍历完,则返回哑节点 $dummy\underline{}head$ 的下一个节点作为头节点。 +- 当指针 $cur$ 的下一个元素或者下下一个元素不存在时,说明已经遍历完,则返回哑节点 $dummy\underline{\hspace{0.5em}}head$ 的下一个节点作为头节点。 ### 思路 1:代码 diff --git "a/Solutions/0124. \344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.md" "b/Solutions/0124. \344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.md" index 043ade00..aa70d4c5 100644 --- "a/Solutions/0124. \344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.md" +++ "b/Solutions/0124. \344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\350\267\257\345\276\204\345\222\214.md" @@ -69,9 +69,9 @@ 在递归时,我们先计算左右子节点的最大贡献值,再更新维护当前最大路径和变量。最终 $ans$ 即为答案。具体步骤如下: 1. 如果根节点 $root$ 为空,则返回 $0$。 -2. 递归计算左子树的最大贡献值为 $left\underline{}max$。 -3. 递归计算右子树的最大贡献值为 $right\underline{}max$。 -4. 更新维护最大路径和变量,即 $self.ans = max \lbrace self.ans, \quad left\underline{}max + right\underline{}max + node.val \rbrace$。 +2. 递归计算左子树的最大贡献值为 $left\underline{\hspace{0.5em}}max$。 +3. 递归计算右子树的最大贡献值为 $right\underline{\hspace{0.5em}}max$。 +4. 更新维护最大路径和变量,即 $self.ans = max \lbrace self.ans, \quad left\underline{\hspace{0.5em}}max + right\underline{\hspace{0.5em}}max + node.val \rbrace$。 5. 返回以当前节点为根节点,并且经过该节点的最大贡献值。即返回 **当前节点值 + 左右子节点提供的最大贡献值中较大的一个**。 6. 最终 $self.ans$ 即为答案。 diff --git "a/Solutions/0133. \345\205\213\351\232\206\345\233\276.md" "b/Solutions/0133. \345\205\213\351\232\206\345\233\276.md" index feed92da..7ed17f1e 100644 --- "a/Solutions/0133. \345\205\213\351\232\206\345\233\276.md" +++ "b/Solutions/0133. \345\205\213\351\232\206\345\233\276.md" @@ -93,10 +93,10 @@ class Solution: 1. 使用哈希表 $visited$ 来存储原图中被访问过的节点和克隆图中对应节点,键值对为「原图被访问过的节点:克隆图中对应节点」。使用队列 $queue$ 存放节点。 2. 根据起始节点 $node$,创建一个新的节点,并将其添加到哈希表 $visited$ 中,即 `visited[node] = Node(node.val, [])`。然后将起始节点放入队列中,即 `queue.append(node)`。 -3. 从队列中取出第一个节点 $node\underline{}u$。访问节点 $node\underline{}u$。 -4. 遍历节点 $node\underline{}u$ 的所有未访问邻接节点 $node\underline{}v$(节点 $node\underline{}v$ 不在 $visited$ 中)。 -5. 根据节点 $node\underline{}v$ 创建一个新的节点,并将其添加到哈希表 $visited$ 中,即 `visited[node_v] = Node(node_v.val, [])`。 -6. 然后将节点 $node\underline{}v$ 放入队列 $queue$ 中,即 `queue.append(node_v)`。 +3. 从队列中取出第一个节点 $node\underline{\hspace{0.5em}}u$。访问节点 $node\underline{\hspace{0.5em}}u$。 +4. 遍历节点 $node\underline{\hspace{0.5em}}u$ 的所有未访问邻接节点 $node\underline{\hspace{0.5em}}v$(节点 $node\underline{\hspace{0.5em}}v$ 不在 $visited$ 中)。 +5. 根据节点 $node\underline{\hspace{0.5em}}v$ 创建一个新的节点,并将其添加到哈希表 $visited$ 中,即 `visited[node_v] = Node(node_v.val, [])`。 +6. 然后将节点 $node\underline{\hspace{0.5em}}v$ 放入队列 $queue$ 中,即 `queue.append(node_v)`。 7. 重复步骤 $3 \sim 6$,直到队列 $queue$ 为空。 8. 广度优先搜索结束,返回起始节点的克隆节点(即 $visited[node]$)。 diff --git "a/Solutions/0209. \351\225\277\345\272\246\346\234\200\345\260\217\347\232\204\345\255\220\346\225\260\347\273\204.md" "b/Solutions/0209. \351\225\277\345\272\246\346\234\200\345\260\217\347\232\204\345\255\220\346\225\260\347\273\204.md" index 7f3c157c..9f6e11f9 100644 --- "a/Solutions/0209. \351\225\277\345\272\246\346\234\200\345\260\217\347\232\204\345\255\220\346\225\260\347\273\204.md" +++ "b/Solutions/0209. \351\225\277\345\272\246\346\234\200\345\260\217\347\232\204\345\255\220\346\225\260\347\273\204.md" @@ -45,8 +45,8 @@ 用滑动窗口来记录连续子数组的和,设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口中的和刚好大于等于 $target$。 1. 一开始,$left$、$right$ 都指向 $0$。 -2. 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{}sum$ 中。 -3. 如果 $window\underline{}sum \ge target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{}sum < target$。 +2. 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{\hspace{0.5em}}sum$ 中。 +3. 如果 $window\underline{\hspace{0.5em}}sum \ge target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{\hspace{0.5em}}sum < target$。 4. 然后继续右移 $right$,直到 $right \ge len(nums)$ 结束。 5. 输出窗口和的最小值作为答案。 diff --git "a/Solutions/0315. \350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.md" "b/Solutions/0315. \350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.md" index 3527604d..7b759380 100644 --- "a/Solutions/0315. \350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.md" +++ "b/Solutions/0315. \350\256\241\347\256\227\345\217\263\344\276\247\345\260\217\344\272\216\345\275\223\345\211\215\345\205\203\347\264\240\347\232\204\344\270\252\346\225\260.md" @@ -43,12 +43,12 @@ ### 思路 1:归并排序 -在使用归并排序对数组进行排序时,每当遇到 $left\underline{}nums[left\underline{}i] \le right\underline{}nums[right\underline{}i]$ 时,意味着:在合并前,左子数组当前元素 $left\underline{}nums[left\underline{}i]$ 右侧一定有 $left\underline{}i$ 个元素比 $left\underline{}nums[left\underline{}i]$ 小。则我们可以在归并排序的同时,记录 $nums[i]$ 右侧小于 $nums[i]$ 的元素的数量。 +在使用归并排序对数组进行排序时,每当遇到 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i] \le right\underline{\hspace{0.5em}}nums[right\underline{\hspace{0.5em}}i]$ 时,意味着:在合并前,左子数组当前元素 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i]$ 右侧一定有 $left\underline{\hspace{0.5em}}i$ 个元素比 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i]$ 小。则我们可以在归并排序的同时,记录 $nums[i]$ 右侧小于 $nums[i]$ 的元素的数量。 1. 将元素值、对应下标、右侧小于 nums[i] 的元素的数量存入数组中。 2. 对其进行归并排序。 -3. 当遇到 $left\underline{}nums[left\underline{}i] \le right\underline{}nums[right\underline{}i]$ 时,记录 $left\underline{}nums[left\underline{}i]$ 右侧比 $left\underline{}nums[left\underline{}i]$ 小的元素数量,即:`left_nums[left_i][2] += right_i`。 -4. 当合并时 $left\underline{}nums[left\underline{}i]$ 仍有剩余时,说明 $left\underline{}nums[left\underline{}i]$ 右侧有 $right\underline{}i$ 个小于 $left\underline{}nums[left\underline{}i]$ 的元素,记录下来,即:`left_nums[left_i][2] += right_i`。 +3. 当遇到 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i] \le right\underline{\hspace{0.5em}}nums[right\underline{\hspace{0.5em}}i]$ 时,记录 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i]$ 右侧比 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i]$ 小的元素数量,即:`left_nums[left_i][2] += right_i`。 +4. 当合并时 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i]$ 仍有剩余时,说明 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i]$ 右侧有 $right\underline{\hspace{0.5em}}i$ 个小于 $left\underline{\hspace{0.5em}}nums[left\underline{\hspace{0.5em}}i]$ 的元素,记录下来,即:`left_nums[left_i][2] += right_i`。 5. 根据下标及右侧小于 $nums[i]$ 的元素的数量,组合出答案数组,并返回答案数组。 ### 思路 1:代码 diff --git "a/Solutions/0349. \344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.md" "b/Solutions/0349. \344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.md" index acde6f9f..557e6034 100644 --- "a/Solutions/0349. \344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.md" +++ "b/Solutions/0349. \344\270\244\344\270\252\346\225\260\347\273\204\347\232\204\344\272\244\351\233\206.md" @@ -68,10 +68,10 @@ class Solution: ### 思路 2:分离双指针 1. 对数组 $nums1$、$nums2$ 先排序。 -2. 使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向第一个数组的第一个元素,即:$left\underline{}1 = 0$,$left\underline{}2$ 指向第二个数组的第一个元素,即:$left\underline{}2 = 0$。 -3. 如果 $nums1[left_1]$ 等于 $nums2[left_2]$,则将其加入答案数组(注意去重),并将 $left\underline{}1$ 和 $left\underline{}2$ 右移。 -4. 如果 $nums1[left_1]$ 小于 $nums2[left_2]$,则将 $left\underline{}1$ 右移。 -5. 如果 $nums1[left_1]$ 大于 $nums2[left_2]$,则将 $left\underline{}2$ 右移。 +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$。 +3. 如果 $nums1[left_1]$ 等于 $nums2[left_2]$,则将其加入答案数组(注意去重),并将 $left\underline{\hspace{0.5em}}1$ 和 $left\underline{\hspace{0.5em}}2$ 右移。 +4. 如果 $nums1[left_1]$ 小于 $nums2[left_2]$,则将 $left\underline{\hspace{0.5em}}1$ 右移。 +5. 如果 $nums1[left_1]$ 大于 $nums2[left_2]$,则将 $left\underline{\hspace{0.5em}}2$ 右移。 6. 最后返回答案数组。 ### 思路 2:代码 diff --git "a/Solutions/0400. \347\254\254 N \344\275\215\346\225\260\345\255\227.md" "b/Solutions/0400. \347\254\254 N \344\275\215\346\225\260\345\255\227.md" index 7f9b0528..914cb2d6 100644 --- "a/Solutions/0400. \347\254\254 N \344\275\215\346\225\260\345\255\227.md" +++ "b/Solutions/0400. \347\254\254 N \344\275\215\346\225\260\345\255\227.md" @@ -53,7 +53,7 @@ 1. 我们可以先找到第 $n$ 位所在整数 $number$ 所对应的位数 $digit$。 2. 同时找到该位数 $digit$ 的起始整数 $start$。 3. 再计算出 $n$ 所在整数 $number$。$number$ 等于从起始数字 $start$ 开始的第 $\lfloor \frac{n - 1}{digit} \rfloor$ 个数字。即 `number = start + (n - 1) // digit`。 -4. 然后确定 $n$ 对应的是数字 $number$ 中的哪一位。即 $digit\underline{}idx = (n - 1) \mod digit$。 +4. 然后确定 $n$ 对应的是数字 $number$ 中的哪一位。即 $digit\underline{\hspace{0.5em}}idx = (n - 1) \mod digit$。 5. 最后返回结果。 ### 思路 1:代码 @@ -90,7 +90,7 @@ class Solution: $n$ 的最大值为 $2^{31} - 1$,约为 $2 \times 10^9$。而 $9$ 位数字有 $9 \times 10^8$ 个,共 $9 \times 9 \times 10^8 = 8.1 \times 10^9 > 2 \times 10 ^ 9$,所以第 $n$ 位所在整数的位数 $digit$ 最多为 $9$ 位,最小为 $1$ 位。即 $digit$ 的取值范围为 $[1, 9]$。 -我们使用二分查找算法得到 $digit$ 之后,还可以计算出不超过 $digit - 1$ 的整数的所有位数和 $pre\underline{}digits = totalDigits(digit - 1)$,则第 $n$ 位数字所在整数在所有 $digit$ 位数中的下标是 $idx = n - pre\underline{}digits - 1$。 +我们使用二分查找算法得到 $digit$ 之后,还可以计算出不超过 $digit - 1$ 的整数的所有位数和 $pre\underline{\hspace{0.5em}}digits = totalDigits(digit - 1)$,则第 $n$ 位数字所在整数在所有 $digit$ 位数中的下标是 $idx = n - pre\underline{\hspace{0.5em}}digits - 1$。 得到下标 $idx$ 后,可以计算出 $n$ 所在整数 $number$。$number$ 等于从起始数字 $10^{digit - 1}$ 开始的第 $\lfloor \frac{idx}{digit} \rfloor$ 个数字。即 `number = 10 ** (digit - 1) + idx // digit`。 diff --git "a/Solutions/0438. \346\211\276\345\210\260\345\255\227\347\254\246\344\270\262\344\270\255\346\211\200\346\234\211\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.md" "b/Solutions/0438. \346\211\276\345\210\260\345\255\227\347\254\246\344\270\262\344\270\255\346\211\200\346\234\211\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.md" index f264ab23..87fdc2a5 100644 --- "a/Solutions/0438. \346\211\276\345\210\260\345\255\227\347\254\246\344\270\262\344\270\255\346\211\200\346\234\211\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.md" +++ "b/Solutions/0438. \346\211\276\345\210\260\345\255\227\347\254\246\344\270\262\344\270\255\346\211\200\346\234\211\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215.md" @@ -48,11 +48,11 @@ 维护一个固定长度为 $len(p)$ 的滑动窗口。于是问题的难点变为了如何判断 $s$ 的子串和 $p$ 是异位词。可以使用两个字典来分别存储 $s$ 的子串中各个字符个数和 $p$ 中各个字符个数。如果两个字典对应的键值全相等,则说明 $s$ 的子串和 $p$ 是异位词。但是这样每一次比较的操作时间复杂度是 $O(n)$,我们可以通过在滑动数组中逐字符比较的方式来减少两个字典之间相互比较的复杂度,并用 $valid$ 记录经过验证的字符个数。整个算法步骤如下: -- 使用哈希表 $need$ 记录 $p$ 中各个字符出现次数。使用字典 $window$ 记录 $s$ 的子串中各个字符出现的次数。使用数组 $res$ 记录答案。使用 $valid$ 记录 $s$ 的子串中经过验证的字符个数。使用 $window\underline{}size$ 表示窗口大小,值为 $len(p)$。使用两个指针 $left$、$right$。分别指向滑动窗口的左右边界。 +- 使用哈希表 $need$ 记录 $p$ 中各个字符出现次数。使用字典 $window$ 记录 $s$ 的子串中各个字符出现的次数。使用数组 $res$ 记录答案。使用 $valid$ 记录 $s$ 的子串中经过验证的字符个数。使用 $window\underline{\hspace{0.5em}}size$ 表示窗口大小,值为 $len(p)$。使用两个指针 $left$、$right$。分别指向滑动窗口的左右边界。 - 一开始,$left$、$right$ 都指向 $0$。 - 如果 $s[right]$ 出现在 $need$ 中,将最右侧字符 $s[right]$ 加入当前窗口 $window$ 中,记录该字符个数。并验证该字符是否和 $need$ 中个对应字符个数相等。如果相等则验证的字符个数加 $1$,即 `valid += 1`。 -- 如果该窗口字符长度大于等于 $window\underline{}size$ 个,即 $right - left + 1 \ge window\underline{}size$。则不断右移 $left$,缩小滑动窗口长度。 - - 如果验证字符个数 $valid$ 等于窗口长度 $window\underline{}size$,则 $s[left, right + 1]$ 为 $p$ 的异位词,所以将 $left$ 加入到答案数组中。 +- 如果该窗口字符长度大于等于 $window\underline{\hspace{0.5em}}size$ 个,即 $right - left + 1 \ge window\underline{\hspace{0.5em}}size$。则不断右移 $left$,缩小滑动窗口长度。 + - 如果验证字符个数 $valid$ 等于窗口长度 $window\underline{\hspace{0.5em}}size$,则 $s[left, right + 1]$ 为 $p$ 的异位词,所以将 $left$ 加入到答案数组中。 - 如果$s[left]$ 在 $need$ 中,则更新窗口中对应字符的个数,同时维护 $valid$ 值。 - 右移 $right$,直到 $right \ge len(nums)$ 结束。 - 输出答案数组 $res$。 diff --git "a/Solutions/0443. \345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.md" "b/Solutions/0443. \345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.md" index 1a39b476..cdf3a4d9 100644 --- "a/Solutions/0443. \345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.md" +++ "b/Solutions/0443. \345\216\213\347\274\251\345\255\227\347\254\246\344\270\262.md" @@ -51,11 +51,11 @@ 题目要求原地修改字符串数组。我们可以使用快慢指针来解决原地修改问题,具体解决方法如下: - 定义两个快慢指针 $slow$,$fast$。其中 $slow$ 指向压缩后的当前字符位置,$fast$ 指向压缩前的当前字符位置。 -- 记录下当前待压缩字符的起始位置 $fast\underline{}start = start$,然后过滤掉连续相同的字符。 -- 将待压缩字符的起始位置的字符存入压缩后的当前字符位置,即 $chars[slow] = chars[fast\underline{}start]$,并向右移动压缩后的当前字符位置,即 $slow += 1$。 +- 记录下当前待压缩字符的起始位置 $fast\underline{\hspace{0.5em}}start = start$,然后过滤掉连续相同的字符。 +- 将待压缩字符的起始位置的字符存入压缩后的当前字符位置,即 $chars[slow] = chars[fast\underline{\hspace{0.5em}}start]$,并向右移动压缩后的当前字符位置,即 $slow += 1$。 - 判断一下待压缩字符的数目是否大于 $1$: - 如果数量为 $1$,则不用记录该数量。 - - 如果数量大于 $1$(即 $fast - fast\underline{}start > 0$),则我们需要将对应数量存入压缩后的当前字符位置。这时候还需要判断一下数量是否大于等于 $10$。 + - 如果数量大于 $1$(即 $fast - fast\underline{\hspace{0.5em}}start > 0$),则我们需要将对应数量存入压缩后的当前字符位置。这时候还需要判断一下数量是否大于等于 $10$。 - 如果数量大于等于 $10$,则需要先将数字从个位到高位转为字符,存入压缩后的当前字符位置(此时数字为反,比如原数字是 $321$,则此时存入后为 $123$)。因为数字为反,所以我们需要将对应位置上的子字符串进行反转。 - 如果数量小于 $10$,则直接将数字存入压缩后的当前字符位置,无需取反。 - 判断完之后向右移动压缩前的当前字符位置 $fast$,然后继续压缩字符串,直到全部压缩完,则返回压缩后的当前字符位置 $slow$ 即为答案。 diff --git "a/Solutions/0474. \344\270\200\345\222\214\351\233\266.md" "b/Solutions/0474. \344\270\200\345\222\214\351\233\266.md" index 7100a833..e177ff0d 100644 --- "a/Solutions/0474. \344\270\200\345\222\214\351\233\266.md" +++ "b/Solutions/0474. \344\270\200\345\222\214\351\233\266.md" @@ -60,10 +60,10 @@ 填满最多由 $i$ 个 $0$ 和 $j$ 个 $1$ 构成的二维背包的最多物品数为下面两种情况中的最大值: -- 使用之前字符串填满容量为 $i - zero\underline{}num$、$j - one\underline{}num$ 的背包的物品数 + 当前字符串价值 +- 使用之前字符串填满容量为 $i - zero\underline{\hspace{0.5em}}num$、$j - one\underline{\hspace{0.5em}}num$ 的背包的物品数 + 当前字符串价值 - 选择之前字符串填满容量为 $i$、$j$ 的物品数。 -则状态转移方程为:$dp[i][j] = max(dp[i][j], dp[i - zero\underline{}num][j - one\underline{}num] + 1)$。 +则状态转移方程为:$dp[i][j] = max(dp[i][j], dp[i - zero\underline{\hspace{0.5em}}num][j - one\underline{\hspace{0.5em}}num] + 1)$。 ###### 4. 初始条件 diff --git "a/Solutions/0480. \346\273\221\345\212\250\347\252\227\345\217\243\344\270\255\344\275\215\346\225\260.md" "b/Solutions/0480. \346\273\221\345\212\250\347\252\227\345\217\243\344\270\255\344\275\215\346\225\260.md" index 84fc869d..245048f6 100644 --- "a/Solutions/0480. \346\273\221\345\212\250\347\252\227\345\217\243\344\270\255\344\275\215\346\225\260.md" +++ "b/Solutions/0480. \346\273\221\345\212\250\347\252\227\345\217\243\344\270\255\344\275\215\346\225\260.md" @@ -52,31 +52,31 @@ 初始化问题: -我们将所有大于中位数的元素放到 $heap\underline{}max$(小顶堆)中,并且元素个数向上取整。然后再将所有小于等于中位数的元素放到 $heap\underline{}min$(大顶堆)中,并且元素个数向下取整。这样当 $k$ 为奇数时,$heap\underline{}max$ 比 $heap\underline{}min$ 多一个元素,中位数就是 $heap\underline{}max$ 堆顶元素。当 $k$ 为偶数时,$heap\underline{}max$ 和 $heap\underline{}min$ 中的元素个数相同,中位数就是 $heap\underline{}min$ 堆顶元素和 $heap\underline{}max$ 堆顶元素的平均数。这个过程操作如下: +我们将所有大于中位数的元素放到 $heap\underline{\hspace{0.5em}}max$(小顶堆)中,并且元素个数向上取整。然后再将所有小于等于中位数的元素放到 $heap\underline{\hspace{0.5em}}min$(大顶堆)中,并且元素个数向下取整。这样当 $k$ 为奇数时,$heap\underline{\hspace{0.5em}}max$ 比 $heap\underline{\hspace{0.5em}}min$ 多一个元素,中位数就是 $heap\underline{\hspace{0.5em}}max$ 堆顶元素。当 $k$ 为偶数时,$heap\underline{\hspace{0.5em}}max$ 和 $heap\underline{\hspace{0.5em}}min$ 中的元素个数相同,中位数就是 $heap\underline{\hspace{0.5em}}min$ 堆顶元素和 $heap\underline{\hspace{0.5em}}max$ 堆顶元素的平均数。这个过程操作如下: -- 先将数组中前 $k$ 个元素放到 $heap\underline{}max$ 中。 -- 再从 $heap\underline{}max$ 中取出 $k // 2$ 个堆顶元素放到 $heap\underline{}min$ 中。 +- 先将数组中前 $k$ 个元素放到 $heap\underline{\hspace{0.5em}}max$ 中。 +- 再从 $heap\underline{\hspace{0.5em}}max$ 中取出 $k // 2$ 个堆顶元素放到 $heap\underline{\hspace{0.5em}}min$ 中。 取中位数问题(上边提到过): -- 当 $k$ 为奇数时,中位数就是 $heap\underline{}max$ 堆顶元素。当 $k$ 为偶数时,中位数就是 $heap\underline{}max$ 堆顶元素和 $heap\underline{}min$ 堆顶元素的平均数。 +- 当 $k$ 为奇数时,中位数就是 $heap\underline{\hspace{0.5em}}max$ 堆顶元素。当 $k$ 为偶数时,中位数就是 $heap\underline{\hspace{0.5em}}max$ 堆顶元素和 $heap\underline{\hspace{0.5em}}min$ 堆顶元素的平均数。 窗口滑动过程中元素的添加和删除问题: - 删除:每次滑动将窗口左侧元素删除。由于 `heapq` 没有提供删除中间特定元素相对应的方法。所以我们使用「延迟删除」的方式先把待删除的元素标记上,等到待删除的元素出现在堆顶时,再将其移除。我们使用 $removes$ (哈希表)来记录待删除元素个数。 - 将窗口左侧元素删除的操作为:`removes[nums[left]] += 1`。 -- 添加:每次滑动在窗口右侧添加元素。需要根据上一步删除的结果来判断需要添加到哪一个堆上。我们用 $banlance$ 记录 $heap\underline{}max$ 和 $heap\underline{}min$ 元素个数的差值。 - - 如果窗口左边界 $nums[left]$小于等于 $heap\underline{}max$ 堆顶元素 ,则说明上一步删除的元素在 $heap\underline{}min$ 上,则让 `banlance -= 1`。 - - 如果窗口左边界 $nums[left]$ 大于 $heap\underline{}max$ 堆顶元素,则说明上一步删除的元素在 $heap\underline{}max$ 上,则上 `banlance += 1`。 - - 如果窗口右边界 $nums[right]$ 小于等于 $heap\underline{}max$ 堆顶元素,则说明待添加元素需要添加到 $heap\underline{}min$ 上,则让 `banlance += 1`。 - - 如果窗口右边界 $nums[right]$ 大于 $heap\underline{}max$ 堆顶元素,则说明待添加元素需要添加到 $heap\underline{}max$ 上,则让 `banlance -= 1`。 +- 添加:每次滑动在窗口右侧添加元素。需要根据上一步删除的结果来判断需要添加到哪一个堆上。我们用 $banlance$ 记录 $heap\underline{\hspace{0.5em}}max$ 和 $heap\underline{\hspace{0.5em}}min$ 元素个数的差值。 + - 如果窗口左边界 $nums[left]$小于等于 $heap\underline{\hspace{0.5em}}max$ 堆顶元素 ,则说明上一步删除的元素在 $heap\underline{\hspace{0.5em}}min$ 上,则让 `banlance -= 1`。 + - 如果窗口左边界 $nums[left]$ 大于 $heap\underline{\hspace{0.5em}}max$ 堆顶元素,则说明上一步删除的元素在 $heap\underline{\hspace{0.5em}}max$ 上,则上 `banlance += 1`。 + - 如果窗口右边界 $nums[right]$ 小于等于 $heap\underline{\hspace{0.5em}}max$ 堆顶元素,则说明待添加元素需要添加到 $heap\underline{\hspace{0.5em}}min$ 上,则让 `banlance += 1`。 + - 如果窗口右边界 $nums[right]$ 大于 $heap\underline{\hspace{0.5em}}max$ 堆顶元素,则说明待添加元素需要添加到 $heap\underline{\hspace{0.5em}}max$ 上,则让 `banlance -= 1`。 - 经过上述操作,$banlance$ 的取值为 $0$、$-2$、$2$ 中的一种。需要经过调整使得 $banlance == 0$。 - 如果 $banlance == 0$,已经平衡,不需要再做操作。 - - 如果 $banlance == -2$,则说明 $heap\underline{}min$ 比 $heap\underline{}max$ 的元素多了两个。则从 $heap\underline{}min$ 中取出堆顶元素添加到 $heap\underline{}max$ 中。 - - 如果 $banlance == 2$,则说明 $heap\underline{}max$ 比 $heap\underline{}min$ 的元素多了两个。则从 $heap\underline{}max$ 中取出堆顶元素添加到 $heap\underline{}min$ 中。 -- 调整完之后,分别检查 $heap\underline{}max$ 和 $heap\underline{}min$ 的堆顶元素。 - - 如果 $heap\underline{}max$ 堆顶元素恰好为待删除元素,即 $removes[-heap\underline{}max[0]] > 0$,则弹出 $heap\underline{}max$ 堆顶元素。 - - 如果 $heap\underline{}min$ 堆顶元素恰好为待删除元素,即 $removes[heap\underline{}min[0]] > 0$,则弹出 $heap\underline{}min$ 堆顶元素。 + - 如果 $banlance == -2$,则说明 $heap\underline{\hspace{0.5em}}min$ 比 $heap\underline{\hspace{0.5em}}max$ 的元素多了两个。则从 $heap\underline{\hspace{0.5em}}min$ 中取出堆顶元素添加到 $heap\underline{\hspace{0.5em}}max$ 中。 + - 如果 $banlance == 2$,则说明 $heap\underline{\hspace{0.5em}}max$ 比 $heap\underline{\hspace{0.5em}}min$ 的元素多了两个。则从 $heap\underline{\hspace{0.5em}}max$ 中取出堆顶元素添加到 $heap\underline{\hspace{0.5em}}min$ 中。 +- 调整完之后,分别检查 $heap\underline{\hspace{0.5em}}max$ 和 $heap\underline{\hspace{0.5em}}min$ 的堆顶元素。 + - 如果 $heap\underline{\hspace{0.5em}}max$ 堆顶元素恰好为待删除元素,即 $removes[-heap\underline{\hspace{0.5em}}max[0]] > 0$,则弹出 $heap\underline{\hspace{0.5em}}max$ 堆顶元素。 + - 如果 $heap\underline{\hspace{0.5em}}min$ 堆顶元素恰好为待删除元素,即 $removes[heap\underline{\hspace{0.5em}}min[0]] > 0$,则弹出 $heap\underline{\hspace{0.5em}}min$ 堆顶元素。 - 最后取中位数放入答案数组中,然后继续滑动窗口。 ### 思路 1:代码 diff --git "a/Solutions/0487. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 II.md" "b/Solutions/0487. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 II.md" index aa181a7a..a7b648ed 100644 --- "a/Solutions/0487. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 II.md" +++ "b/Solutions/0487. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 II.md" @@ -43,11 +43,11 @@ 我们可以使用滑动窗口来解决问题。保证滑动窗口内最多有 $1$ 个 $0$。具体做法如下: -设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证滑动窗口内最多有 $1$ 个 $0$。使用 $zero\underline{}count$ 统计窗口内 $1$ 的个数。使用 $ans$ 记录答案。 +设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证滑动窗口内最多有 $1$ 个 $0$。使用 $zero\underline{\hspace{0.5em}}count$ 统计窗口内 $1$ 的个数。使用 $ans$ 记录答案。 - 一开始,$left$、$right$ 都指向 $0$。 - 如果 $nums[right] == 0$,则窗口内 $1$ 的个数加 $1$。 -- 如果该窗口中 $1$ 的个数多于 $1$ 个,即 $zero\underline{}count > 1$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口中 $1$ 的个数,直到 $zero\underline{}count \le 1$。 +- 如果该窗口中 $1$ 的个数多于 $1$ 个,即 $zero\underline{\hspace{0.5em}}count > 1$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口中 $1$ 的个数,直到 $zero\underline{\hspace{0.5em}}count \le 1$。 - 维护更新最大连续 $1$ 的个数。然后右移 $right$,直到 $right \ge len(nums)$ 结束。 - 输出最大连续 $1$ 的个数。 diff --git "a/Solutions/0494. \347\233\256\346\240\207\345\222\214.md" "b/Solutions/0494. \347\233\256\346\240\207\345\222\214.md" index b58181c6..51b3a352 100644 --- "a/Solutions/0494. \347\233\256\346\240\207\345\222\214.md" +++ "b/Solutions/0494. \347\233\256\346\240\207\345\222\214.md" @@ -51,11 +51,11 @@ 1. 定义从位置 $0$、和为 $0$ 开始,到达数组尾部位置为止,和为 $target$ 的方案数为 `dfs(0, 0)`。 2. 下面从位置 $0$、和为 $0$ 开始,以深度优先搜索遍历每个位置。 3. 如果当前位置 $i$ 到达最后一个位置 $size$: - 1. 如果和 $cur\underline{}sum$ 等于目标和 $target$,则返回方案数 $1$。 - 2. 如果和 $cur\underline{}sum$ 不等于目标和 $target$,则返回方案数 $0$。 -4. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum - nums[i]$ 的方案数。 -5. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum + nums[i]$ 的方案数。 -6. 将 4 ~ 5 两个方案数加起来就是当前位置 $i$、和为 $cur\underline{}sum$ 的方案数,返回该方案数。 + 1. 如果和 $cur\underline{\hspace{0.5em}}sum$ 等于目标和 $target$,则返回方案数 $1$。 + 2. 如果和 $cur\underline{\hspace{0.5em}}sum$ 不等于目标和 $target$,则返回方案数 $0$。 +4. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum - nums[i]$ 的方案数。 +5. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum + nums[i]$ 的方案数。 +6. 将 4 ~ 5 两个方案数加起来就是当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 的方案数,返回该方案数。 7. 最终方案数为 `dfs(0, 0)`,将其作为答案返回即可。 ### 思路 1:代码 @@ -86,18 +86,18 @@ class Solution: 在思路 1 中我们单独使用深度优先搜索对每位数字进行 `+` 或者 `-` 的方法超时了。所以我们考虑使用记忆化搜索的方式,避免进行重复搜索。 -这里我们使用哈希表 $$table$$ 记录遍历过的位置 $i$ 及所得到的的当前和 $cur\underline{}sum$ 下的方案数,来避免重复搜索。具体步骤如下: +这里我们使用哈希表 $$table$$ 记录遍历过的位置 $i$ 及所得到的的当前和 $cur\underline{\hspace{0.5em}}sum$ 下的方案数,来避免重复搜索。具体步骤如下: 1. 定义从位置 $0$、和为 $0$ 开始,到达数组尾部位置为止,和为 $target$ 的方案数为 `dfs(0, 0)`。 2. 下面从位置 $0$、和为 $0$ 开始,以深度优先搜索遍历每个位置。 3. 如果当前位置 $i$ 遍历完所有位置: - 1. 如果和 $cur\underline{}sum$ 等于目标和 $target$,则返回方案数 $1$。 - 2. 如果和 $cur\underline{}sum$ 不等于目标和 $target$,则返回方案数 $0$。 -4. 如果当前位置 $i$、和为 $cur\underline{}sum$ 之前记录过(即使用 $table$ 记录过对应方案数),则返回该方案数。 -5. 如果当前位置 $i$、和为 $cur\underline{}sum$ 之前没有记录过,则: - 1. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum - nums[i]$ 的方案数。 - 2. 递归搜索 $i + 1$ 位置,和为 $cur\underline{}sum + nums[i]$ 的方案数。 - 3. 将上述两个方案数加起来就是当前位置 $i$、和为 $cur\underline{}sum$ 的方案数,将其记录到哈希表 $table$ 中,并返回该方案数。 + 1. 如果和 $cur\underline{\hspace{0.5em}}sum$ 等于目标和 $target$,则返回方案数 $1$。 + 2. 如果和 $cur\underline{\hspace{0.5em}}sum$ 不等于目标和 $target$,则返回方案数 $0$。 +4. 如果当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 之前记录过(即使用 $table$ 记录过对应方案数),则返回该方案数。 +5. 如果当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 之前没有记录过,则: + 1. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum - nums[i]$ 的方案数。 + 2. 递归搜索 $i + 1$ 位置,和为 $cur\underline{\hspace{0.5em}}sum + nums[i]$ 的方案数。 + 3. 将上述两个方案数加起来就是当前位置 $i$、和为 $cur\underline{\hspace{0.5em}}sum$ 的方案数,将其记录到哈希表 $table$ 中,并返回该方案数。 6. 最终方案数为 `dfs(0, 0)`,将其作为答案返回即可。 ### 思路 2:代码 @@ -132,9 +132,9 @@ class Solution: ### 思路 3:动态规划 -假设数组中所有元素和为 $sum$,数组中所有符号为 `+` 的元素为 $sum\underline{}x$,符号为 `-` 的元素和为 $sum\underline{}y$。则 $target = sum\underline{}x - sum\underline{}y$。 +假设数组中所有元素和为 $sum$,数组中所有符号为 `+` 的元素为 $sum\underline{\hspace{0.5em}}x$,符号为 `-` 的元素和为 $sum\underline{\hspace{0.5em}}y$。则 $target = sum\underline{\hspace{0.5em}}x - sum\underline{\hspace{0.5em}}y$。 -而 $sum\underline{}x + sum\underline{}y = sum$。根据两个式子可以求出 $2 \times sum\underline{}x = target + sum$,即 $sum\underline{}x = (target + sum) / 2$。 +而 $sum\underline{\hspace{0.5em}}x + sum\underline{\hspace{0.5em}}y = sum$。根据两个式子可以求出 $2 \times sum\underline{\hspace{0.5em}}x = target + sum$,即 $sum\underline{\hspace{0.5em}}x = (target + sum) / 2$。 那么这道题就变成了,如何在数组中找到一个集合,使集合中元素和为 $(target + sum) / 2$。这就变为了「0-1 背包问题」中求装满背包的方案数问题。 diff --git "a/Solutions/0526. \344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.md" "b/Solutions/0526. \344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.md" index e9491752..7aef3834 100644 --- "a/Solutions/0526. \344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.md" +++ "b/Solutions/0526. \344\274\230\347\276\216\347\232\204\346\216\222\345\210\227.md" @@ -175,9 +175,9 @@ class Solution: 对于状态 $state$,先统计出 $state$ 中选择的数字个数(即统计二进制中 $1$ 的个数)$one_num$。 -则 $dp[state]$ 表示选择了前 $one\underline{}num$ 个数字,且选择情况为 $state$ 时的方案数。 +则 $dp[state]$ 表示选择了前 $one\underline{\hspace{0.5em}}num$ 个数字,且选择情况为 $state$ 时的方案数。 -$dp[state]$ 的状态肯定是由前 $one\underline{}num - 1$ 个数字,且 $state$ 第 $k$ 位为 $0$ 的状态而来对应状态转移而来,即:$dp[state \oplus (1 << (k - 1))]$。 +$dp[state]$ 的状态肯定是由前 $one\underline{\hspace{0.5em}}num - 1$ 个数字,且 $state$ 第 $k$ 位为 $0$ 的状态而来对应状态转移而来,即:$dp[state \oplus (1 << (k - 1))]$。 所以状态转移方程为:$dp[state] = \sum_{k = 1}^n dp[state \oplus (1 << (k - 1))]$ diff --git "a/Solutions/0560. \345\222\214\344\270\272 K \347\232\204\345\255\220\346\225\260\347\273\204.md" "b/Solutions/0560. \345\222\214\344\270\272 K \347\232\204\345\255\220\346\225\260\347\273\204.md" index 32b1243c..76b25a8f 100644 --- "a/Solutions/0560. \345\222\214\344\270\272 K \347\232\204\345\255\220\346\225\260\347\273\204.md" +++ "b/Solutions/0560. \345\222\214\344\270\272 K \347\232\204\345\255\220\346\225\260\347\273\204.md" @@ -76,23 +76,23 @@ class Solution: ### 思路 2:前缀和 + 哈希表 -先用一重循环遍历数组,计算出数组 $nums$ 中前 $j$ 个元素的和(前缀和),保存到一维数组 $pre\underline{}sum$ 中,那么对于任意 $nums[i]…nums[j]$ 的子数组的和为 $pre\underline{}sum[j] - pre\underline{}sum[i - 1]$。这样计算子数组和的时间复杂度降为了 $O(1)$。总体时间复杂度为 $O(n^2)$。 +先用一重循环遍历数组,计算出数组 $nums$ 中前 $j$ 个元素的和(前缀和),保存到一维数组 $pre\underline{\hspace{0.5em}}sum$ 中,那么对于任意 $nums[i]…nums[j]$ 的子数组的和为 $pre\underline{\hspace{0.5em}}sum[j] - pre\underline{\hspace{0.5em}}sum[i - 1]$。这样计算子数组和的时间复杂度降为了 $O(1)$。总体时间复杂度为 $O(n^2)$。 但是还是超时了。。 由于我们只关心和为 $k$ 出现的次数,不关心具体的解,可以使用哈希表来加速运算。 -$pre\underline{}sum[i]$ 的定义是前 $i$ 个元素和,则 $pre\underline{}sum[i]$ 可以由 $pre\underline{}sum[i - 1]$ 递推而来,即:$pre\underline{}sum[i] = pre\underline{}sum[i - 1] + num[i]$。 $[i..j]$ 子数组和为 $k$ 可以转换为:$pre\underline{}sum[j] - pre\underline{}sum[i - 1] == k$。 +$pre\underline{\hspace{0.5em}}sum[i]$ 的定义是前 $i$ 个元素和,则 $pre\underline{\hspace{0.5em}}sum[i]$ 可以由 $pre\underline{\hspace{0.5em}}sum[i - 1]$ 递推而来,即:$pre\underline{\hspace{0.5em}}sum[i] = pre\underline{\hspace{0.5em}}sum[i - 1] + num[i]$。 $[i..j]$ 子数组和为 $k$ 可以转换为:$pre\underline{\hspace{0.5em}}sum[j] - pre\underline{\hspace{0.5em}}sum[i - 1] == k$。 -综合一下,可得:$pre\underline{}sum[i - 1] == pre\underline{}sum[j] - k $。 +综合一下,可得:$pre\underline{\hspace{0.5em}}sum[i - 1] == pre\underline{\hspace{0.5em}}sum[j] - k $。 -所以,当我们考虑以 $j$ 结尾和为 $k$ 的连续子数组个数时,只需要统计有多少个前缀和为 $pre\underline{}sum[j] - k$ (即 $pre\underline{}sum[i - 1]$)的个数即可。具体做法如下: +所以,当我们考虑以 $j$ 结尾和为 $k$ 的连续子数组个数时,只需要统计有多少个前缀和为 $pre\underline{\hspace{0.5em}}sum[j] - k$ (即 $pre\underline{\hspace{0.5em}}sum[i - 1]$)的个数即可。具体做法如下: -- 使用 $pre\underline{}sum$ 变量记录前缀和(代表 $pre\underline{}sum[j]$)。 -- 使用哈希表 $pre\underline{}dic$ 记录 $pre\underline{}sum[j]$ 出现的次数。键值对为 $pre\underline{}sum[j] : pre\underline{}sum\underline{}count$。 -- 从左到右遍历数组,计算当前前缀和 $pre\underline{}sum$。 -- 如果 $pre\underline{}sum - k$ 在哈希表中,则答案个数累加上 $pre\underline{}dic[pre\underline{}sum - k]$。 -- 如果 $pre\underline{}sum$ 在哈希表中,则前缀和个数累加 $1$,即 $pre\underline{}dic[pre\underline{}sum] += 1$。 +- 使用 $pre\underline{\hspace{0.5em}}sum$ 变量记录前缀和(代表 $pre\underline{\hspace{0.5em}}sum[j]$)。 +- 使用哈希表 $pre\underline{\hspace{0.5em}}dic$ 记录 $pre\underline{\hspace{0.5em}}sum[j]$ 出现的次数。键值对为 $pre\underline{\hspace{0.5em}}sum[j] : pre\underline{\hspace{0.5em}}sum\underline{\hspace{0.5em}}count$。 +- 从左到右遍历数组,计算当前前缀和 $pre\underline{\hspace{0.5em}}sum$。 +- 如果 $pre\underline{\hspace{0.5em}}sum - k$ 在哈希表中,则答案个数累加上 $pre\underline{\hspace{0.5em}}dic[pre\underline{\hspace{0.5em}}sum - k]$。 +- 如果 $pre\underline{\hspace{0.5em}}sum$ 在哈希表中,则前缀和个数累加 $1$,即 $pre\underline{\hspace{0.5em}}dic[pre\underline{\hspace{0.5em}}sum] += 1$。 - 最后输出答案个数。 ### 思路 2:代码 diff --git "a/Solutions/0567. \345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.md" "b/Solutions/0567. \345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.md" index 752a1525..bf8a5e05 100644 --- "a/Solutions/0567. \345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.md" +++ "b/Solutions/0567. \345\255\227\347\254\246\344\270\262\347\232\204\346\216\222\345\210\227.md" @@ -41,15 +41,15 @@ 题目要求判断 $s2$ 是否包含 $s1$ 的排列,则 $s2$ 的子串长度等于 $s1$ 的长度。我们可以维护一个长度为字符串 $s1$ 长度的固定长度的滑动窗口。 -先统计出字符串 $s1$ 中各个字符的数量,我们用 $s1\underline{}count$ 来表示。这个过程可以用字典、数组来实现,也可以直接用 `collections.Counter()` 实现。再统计 $s2$ 对应窗口内的字符数量 $window\underline{}count$,然后不断向右滑动,然后进行比较。如果对应字符数量相同,则返回 $True$,否则继续滑动。直到末尾时,返回 $False$。整个解题步骤具体如下: +先统计出字符串 $s1$ 中各个字符的数量,我们用 $s1\underline{\hspace{0.5em}}count$ 来表示。这个过程可以用字典、数组来实现,也可以直接用 `collections.Counter()` 实现。再统计 $s2$ 对应窗口内的字符数量 $window\underline{\hspace{0.5em}}count$,然后不断向右滑动,然后进行比较。如果对应字符数量相同,则返回 $True$,否则继续滑动。直到末尾时,返回 $False$。整个解题步骤具体如下: -1. $s1\underline{}count$ 用来统计 $s1$ 中各个字符数量。$window\underline{}count$ 用来维护窗口中 $s2$ 对应子串的各个字符数量。$window\underline{}size$ 表示固定窗口的长度,值为 $len(s1)$。 +1. $s1\underline{\hspace{0.5em}}count$ 用来统计 $s1$ 中各个字符数量。$window\underline{\hspace{0.5em}}count$ 用来维护窗口中 $s2$ 对应子串的各个字符数量。$window\underline{\hspace{0.5em}}size$ 表示固定窗口的长度,值为 $len(s1)$。 2. 先统计出 $s1$ 中各个字符数量。 3. $left$ 、$right$ 都指向序列的第一个元素,即:`left = 0`,`right = 0`。 4. 向右移动 $right$,先将 $len(s1)$ 个元素填入窗口中。 -5. 当窗口元素个数为 $window\underline{}size$ 时,即:$right - left + 1 \ge window\underline{}size$ 时,判断窗口内各个字符数量 $window\underline{}count$ 是否等于 $s1 $ 中各个字符数量 $s1\underline{}count$。 +5. 当窗口元素个数为 $window\underline{\hspace{0.5em}}size$ 时,即:$right - left + 1 \ge window\underline{\hspace{0.5em}}size$ 时,判断窗口内各个字符数量 $window\underline{\hspace{0.5em}}count$ 是否等于 $s1 $ 中各个字符数量 $s1\underline{\hspace{0.5em}}count$。 1. 如果等于,直接返回 $True$。 - 2. 如果不等于,则向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{}size$。 + 2. 如果不等于,则向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{\hspace{0.5em}}size$。 6. 重复 $4 \sim 5$ 步,直到 $right$ 到达数组末尾。返回 $False$。 ### 思路 1:代码 diff --git "a/Solutions/0643. \345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.md" "b/Solutions/0643. \345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.md" index c1d4a8aa..bcae8639 100644 --- "a/Solutions/0643. \345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.md" +++ "b/Solutions/0643. \345\255\220\346\225\260\347\273\204\346\234\200\345\244\247\345\271\263\345\235\207\346\225\260 I.md" @@ -43,7 +43,7 @@ 这道题目是典型的固定窗口大小的滑动窗口题目。窗口大小为 $k$。具体做法如下: -1. $ans$ 用来维护子数组最大平均数,初始值为负无穷,即 `float('-inf')`。$window\underline{}total$ 用来维护窗口中元素的和。 +1. $ans$ 用来维护子数组最大平均数,初始值为负无穷,即 `float('-inf')`。$window\underline{\hspace{0.5em}}total$ 用来维护窗口中元素的和。 2. $left$ 、$right$ 都指向序列的第一个元素,即:`left = 0`,`right = 0`。 3. 向右移动 $right$,先将 $k$ 个元素填入窗口中。 4. 当窗口元素个数为 $k$ 时,即:$right - left + 1 >= k$ 时,计算窗口内的元素和平均值,并维护子数组最大平均数。 diff --git "a/Solutions/0674. \346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" "b/Solutions/0674. \346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" index 0caec528..8701a725 100644 --- "a/Solutions/0674. \346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" +++ "b/Solutions/0674. \346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" @@ -89,14 +89,14 @@ class Solution: ### 思路 2:滑动窗口(不定长度) -1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内为连续递增序列。使用 $window\underline{}len$ 存储当前窗口大小,使用 $max\underline{}len$ 维护最大窗口长度。 +1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内为连续递增序列。使用 $window\underline{\hspace{0.5em}}len$ 存储当前窗口大小,使用 $max\underline{\hspace{0.5em}}len$ 维护最大窗口长度。 2. 一开始,$left$、$right$ 都指向 $0$。 3. 将最右侧元素 $nums[right]$ 加入当前连续递增序列中,即当前窗口长度加 $1$(`window_len += 1`)。 4. 判断当前元素 $nums[right]$ 是否满足连续递增序列。 5. 如果 $right > 0$ 并且 $nums[right - 1] \ge nums[right]$ ,说明不满足连续递增序列,则将 $left$ 移动到窗口最右侧,重置当前窗口长度为 $1$(`window_len = 1`)。 6. 记录当前连续递增序列的长度,并更新最长连续递增序列的长度。 7. 继续右移 $right$,直到 $right \ge len(nums)$ 结束。 -8. 输出最长连续递增序列的长度 $max\underline{}len$。 +8. 输出最长连续递增序列的长度 $max\underline{\hspace{0.5em}}len$。 ### 思路 2:代码 diff --git "a/Solutions/0691. \350\264\264\347\272\270\346\213\274\350\257\215.md" "b/Solutions/0691. \350\264\264\347\272\270\346\213\274\350\257\215.md" index b3886ab0..3bbd6858 100644 --- "a/Solutions/0691. \350\264\264\347\272\270\346\213\274\350\257\215.md" +++ "b/Solutions/0691. \350\264\264\347\272\270\346\213\274\350\257\215.md" @@ -51,13 +51,13 @@ 然后我们从初始状态 $state = 0$(没有选中 $target$ 中的任何字母)开始进行广度优先搜索遍历。 -在广度优先搜索过程中,对于当前状态 $cur\underline{}state$,我们遍历所有贴纸的所有字母,如果当前字母可以拼到 $target$ 中的某个位置上,则更新状态 $next\underline{}state$ 为「选中 $target$ 中对应位置上的字母」。 +在广度优先搜索过程中,对于当前状态 $cur\underline{\hspace{0.5em}}state$,我们遍历所有贴纸的所有字母,如果当前字母可以拼到 $target$ 中的某个位置上,则更新状态 $next\underline{\hspace{0.5em}}state$ 为「选中 $target$ 中对应位置上的字母」。 为了得到最小最小贴纸数量,我们可以使用动态规划的方法,定义 $dp[state]$ 表示为到达 $state$ 状态需要的最小贴纸数量。 -那么在广度优先搜索中,在更新状态时,同时进行状态转移,即 $dp[next\underline{}state] = dp[cur\underline{}state] + 1$。 +那么在广度优先搜索中,在更新状态时,同时进行状态转移,即 $dp[next\underline{\hspace{0.5em}}state] = dp[cur\underline{\hspace{0.5em}}state] + 1$。 -> 注意:在进行状态转移时,要跳过 $dp[next\underline{}state]$ 已经有值的情况。 +> 注意:在进行状态转移时,要跳过 $dp[next\underline{\hspace{0.5em}}state]$ 已经有值的情况。 这样在到达状态 $1 \text{ <}\text{< } len(target) - 1$ 时,所得到的 $dp[1 \text{ <}\text{< } len(target) - 1]$ 即为答案。 diff --git "a/Solutions/0695. \345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.md" "b/Solutions/0695. \345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.md" index fa2528e3..1c67bcaa 100644 --- "a/Solutions/0695. \345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.md" +++ "b/Solutions/0695. \345\262\233\345\261\277\347\232\204\346\234\200\345\244\247\351\235\242\347\247\257.md" @@ -85,7 +85,7 @@ class Solution: 1. 使用 $ans$ 记录最大岛屿面积。 2. 遍历二维数组的每一个元素,对于每个值为 $1$ 的元素: - 1. 将该元素置为 $0$。并使用队列 $queue$ 存储该节点位置。使用 $temp\underline{}ans$ 记录当前岛屿面积。 + 1. 将该元素置为 $0$。并使用队列 $queue$ 存储该节点位置。使用 $temp\underline{\hspace{0.5em}}ans$ 记录当前岛屿面积。 2. 然后从队列 $queue$ 中取出第一个节点位置 $(i, j)$。遍历该节点位置上、下、左、右四个方向上的相邻节点。并将其置为 $0$(避免重复搜索)。并将其加入到队列中。并累加当前岛屿面积,即 `temp_ans += 1`。 3. 不断重复上一步骤,直到队列 $queue$ 为空。 4. 更新当前最大岛屿面积,即 `ans = max(ans, temp_ans)`。 diff --git "a/Solutions/0698. \345\210\222\345\210\206\344\270\272k\344\270\252\347\233\270\347\255\211\347\232\204\345\255\220\351\233\206.md" "b/Solutions/0698. \345\210\222\345\210\206\344\270\272k\344\270\252\347\233\270\347\255\211\347\232\204\345\255\220\351\233\206.md" index a1983260..a58e36f0 100644 --- "a/Solutions/0698. \345\210\222\345\210\206\344\270\272k\344\270\252\347\233\270\347\255\211\347\232\204\345\255\220\351\233\206.md" +++ "b/Solutions/0698. \345\210\222\345\210\206\344\270\272k\344\270\252\347\233\270\347\255\211\347\232\204\345\255\220\351\233\206.md" @@ -62,10 +62,10 @@ 1. 当数组元素选择情况为 $state$ 时可行,即 $dp[state] == True$; 2. 第 $i$ 位数字没有被使用; -3. 加上第 $i$ 位元素后的状态为 $next\underline{}state$; +3. 加上第 $i$ 位元素后的状态为 $next\underline{\hspace{0.5em}}state$; 4. 加上第 $i$ 位元素后没有超出目标和。 -则:$dp[next\underline{}state] = True$。 +则:$dp[next\underline{\hspace{0.5em}}state] = True$。 ###### 4. 初始条件 diff --git "a/Solutions/0713. \344\271\230\347\247\257\345\260\217\344\272\216 K \347\232\204\345\255\220\346\225\260\347\273\204.md" "b/Solutions/0713. \344\271\230\347\247\257\345\260\217\344\272\216 K \347\232\204\345\255\220\346\225\260\347\273\204.md" index 4acba49e..459ffe21 100644 --- "a/Solutions/0713. \344\271\230\347\247\257\345\260\217\344\272\216 K \347\232\204\345\255\220\346\225\260\347\273\204.md" +++ "b/Solutions/0713. \344\271\230\347\247\257\345\260\217\344\272\216 K \347\232\204\345\255\220\346\225\260\347\273\204.md" @@ -40,10 +40,10 @@ ### 思路 1:滑动窗口(不定长度) -1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内所有数的乘积 $window\underline{}product$ 都小于 $k$。使用 $window\underline{}product$ 记录窗口中的乘积值,使用 $count$ 记录符合要求的子数组个数。 +1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内所有数的乘积 $window\underline{\hspace{0.5em}}product$ 都小于 $k$。使用 $window\underline{\hspace{0.5em}}product$ 记录窗口中的乘积值,使用 $count$ 记录符合要求的子数组个数。 2. 一开始,$left$、$right$ 都指向 $0$。 -3. 向右移动 $right$,将最右侧元素加入当前子数组乘积 $window\underline{}product$ 中。 -4. 如果 $window\underline{}product \ge k$,则不断右移 $left$,缩小滑动窗口长度,并更新当前乘积值 $window\underline{}product$ 直到 $window\underline{}product < k$。 +3. 向右移动 $right$,将最右侧元素加入当前子数组乘积 $window\underline{\hspace{0.5em}}product$ 中。 +4. 如果 $window\underline{\hspace{0.5em}}product \ge k$,则不断右移 $left$,缩小滑动窗口长度,并更新当前乘积值 $window\underline{\hspace{0.5em}}product$ 直到 $window\underline{\hspace{0.5em}}product < k$。 5. 记录累积答案个数加 $1$,继续右移 $right$,直到 $right \ge len(nums)$ 结束。 6. 输出累积答案个数。 diff --git "a/Solutions/0803. \346\211\223\347\240\226\345\235\227.md" "b/Solutions/0803. \346\211\223\347\240\226\345\235\227.md" index 9d0fc81d..8070f4b6 100644 --- "a/Solutions/0803. \346\211\223\347\240\226\345\235\227.md" +++ "b/Solutions/0803. \346\211\223\347\240\226\345\235\227.md" @@ -90,10 +90,10 @@ 整个算法步骤具体如下: -1. 先将二维数组 $grid$ 复制一份到二维数组 $copy\underline{}gird$ 上。这是因为遍历 $hits$ 元素时需要判断原网格是空白还是被打碎的砖块。 -2. 在 $copy\underline{}grid$ 中将 $hits$ 中打碎的砖块赋值为 $0$。 +1. 先将二维数组 $grid$ 复制一份到二维数组 $copy\underline{\hspace{0.5em}}gird$ 上。这是因为遍历 $hits$ 元素时需要判断原网格是空白还是被打碎的砖块。 +2. 在 $copy\underline{\hspace{0.5em}}grid$ 中将 $hits$ 中打碎的砖块赋值为 $0$。 3. 建立并查集,将房顶上的砖块合并到一个集合中。 -4. 逆序遍历 $hits$,将 $hits$ 中的砖块补到 $copy\underline{}grid$ 中,并计算每一步中有多少个砖块粘到屋顶上(与屋顶砖块在一个集合中),并存入答案数组对应位置。 +4. 逆序遍历 $hits$,将 $hits$ 中的砖块补到 $copy\underline{\hspace{0.5em}}grid$ 中,并计算每一步中有多少个砖块粘到屋顶上(与屋顶砖块在一个集合中),并存入答案数组对应位置。 5. 最后输出答案数组。 ### 思路 1:代码 diff --git "a/Solutions/0806. \345\206\231\345\255\227\347\254\246\344\270\262\351\234\200\350\246\201\347\232\204\350\241\214\346\225\260.md" "b/Solutions/0806. \345\206\231\345\255\227\347\254\246\344\270\262\351\234\200\350\246\201\347\232\204\350\241\214\346\225\260.md" index e919b4cb..13ec0704 100644 --- "a/Solutions/0806. \345\206\231\345\255\227\347\254\246\344\270\262\351\234\200\350\246\201\347\232\204\350\241\214\346\225\260.md" +++ "b/Solutions/0806. \345\206\231\345\255\227\347\254\246\344\270\262\351\234\200\350\246\201\347\232\204\350\241\214\346\225\260.md" @@ -51,7 +51,7 @@ S = "bbbcccdddaaa" ### 思路 1:模拟 -1. 使用变量 $line\underline{}cnt$ 记录行数,使用变量 $last\underline{}cnt$ 记录最后一行使用的单位数。 +1. 使用变量 $line\underline{\hspace{0.5em}}cnt$ 记录行数,使用变量 $last\underline{\hspace{0.5em}}cnt$ 记录最后一行使用的单位数。 2. 遍历字符串,如果当前最后一行使用的单位数 + 当前字符需要的单位超过了 $100$,则: 1. 另起一行填充字符。(即行数加 $1$,最后一行使用的单位数为当前字符宽度)。 3. 如果当前最后一行使用的单位数 + 当前字符需要的单位没有超过 $100$,则: diff --git "a/Solutions/0819. \346\234\200\345\270\270\350\247\201\347\232\204\345\215\225\350\257\215.md" "b/Solutions/0819. \346\234\200\345\270\270\350\247\201\347\232\204\345\215\225\350\257\215.md" index 0fc0d9fe..0cf6940f 100644 --- "a/Solutions/0819. \346\234\200\345\270\270\350\247\201\347\232\204\345\215\225\350\257\215.md" +++ "b/Solutions/0819. \346\234\200\345\270\270\350\247\201\347\232\204\345\215\225\350\257\215.md" @@ -55,7 +55,7 @@ banned = [] ### 思路 1:哈希表 -1. 将禁用词列表转为集合 $banned\underline{}set$。 +1. 将禁用词列表转为集合 $banned\underline{\hspace{0.5em}}set$。 2. 遍历段落 $paragraph$,获取段落中的所有单词。 3. 判断当前单词是否在禁用词集合中,如果不在禁用词集合中,则使用哈希表对该单词进行计数。 4. 遍历完,找出哈希表中频率最大的单词,将该单词作为答案进行返回。 diff --git "a/Solutions/0844. \346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.md" "b/Solutions/0844. \346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.md" index 19311b32..b1cd1e02 100644 --- "a/Solutions/0844. \346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.md" +++ "b/Solutions/0844. \346\257\224\350\276\203\345\220\253\351\200\200\346\240\274\347\232\204\345\255\227\347\254\246\344\270\262.md" @@ -75,19 +75,19 @@ class Solution: 由于 `#` 会消除左侧字符,而不会影响右侧字符,所以我们选择从字符串尾端遍历 $s$、$t$ 字符串。具体做法如下: -- 使用分离双指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向字符串 $s$ 末尾,$left\underline{}2$ 指向字符串 $t$ 末尾。使用 $sign\underline{}1$、$sign\underline{}2$ 标记字符串 $s$、$t$ 中当前退格字符个数。 +- 使用分离双指针 $left\underline{\hspace{0.5em}}1$、$left\underline{\hspace{0.5em}}2$。$left\underline{\hspace{0.5em}}1$ 指向字符串 $s$ 末尾,$left\underline{\hspace{0.5em}}2$ 指向字符串 $t$ 末尾。使用 $sign\underline{\hspace{0.5em}}1$、$sign\underline{\hspace{0.5em}}2$ 标记字符串 $s$、$t$ 中当前退格字符个数。 - 从后到前遍历字符串 $s$、$t$。 - 先来循环处理字符串 $s$ 尾端 `#` 的影响,具体如下: - - 如果当前字符是 `#`,则更新 $s$ 当前退格字符个数,即 `sign_1 += 1`。同时将 $left\underline{}1$ 左移。 - - 如果 $s$ 当前退格字符个数大于 $0$,则退格数减一,即 `sign_1 -= 1`。同时将 $left\underline{}1$ 左移。 + - 如果当前字符是 `#`,则更新 $s$ 当前退格字符个数,即 `sign_1 += 1`。同时将 $left\underline{\hspace{0.5em}}1$ 左移。 + - 如果 $s$ 当前退格字符个数大于 $0$,则退格数减一,即 `sign_1 -= 1`。同时将 $left\underline{\hspace{0.5em}}1$ 左移。 - 如果 $s$ 当前为普通字符,则跳出循环。 - 同理再来处理字符串 $t$ 尾端 `#` 的影响,具体如下: - - 如果当前字符是 `#`,则更新 $t$ 当前退格字符个数,即 `sign_2 += 1`。同时将 $left\underline{}2$ 左移。 - - 如果 $t$ 当前退格字符个数大于 $0$,则退格数减一,即 `sign_2 -= 1`。同时将 $left\underline{}2$ 左移。 + - 如果当前字符是 `#`,则更新 $t$ 当前退格字符个数,即 `sign_2 += 1`。同时将 $left\underline{\hspace{0.5em}}2$ 左移。 + - 如果 $t$ 当前退格字符个数大于 $0$,则退格数减一,即 `sign_2 -= 1`。同时将 $left\underline{\hspace{0.5em}}2$ 左移。 - 如果 $t$ 当前为普通字符,则跳出循环。 - 处理完,如果两个字符串为空,则说明匹配,直接返回 $True$。 - 再先排除长度不匹配的情况,直接返回 $False$。 - - 最后判断 $s[left\underline{}1]$ 是否等于 $s[left\underline{}2]$。不等于则直接返回 $False$,等于则令 $left\underline{}1$、$left\underline{}2$ 左移,继续遍历。 + - 最后判断 $s[left\underline{\hspace{0.5em}}1]$ 是否等于 $s[left\underline{\hspace{0.5em}}2]$。不等于则直接返回 $False$,等于则令 $left\underline{\hspace{0.5em}}1$、$left\underline{\hspace{0.5em}}2$ 左移,继续遍历。 - 遍历完没有出现不匹配的情况,则返回 $True$。 ### 思路 2:代码 diff --git "a/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" "b/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" index 8bef1d78..300f2347 100644 --- "a/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" +++ "b/Solutions/0862. \345\222\214\350\207\263\345\260\221\344\270\272 K \347\232\204\346\234\200\347\237\255\345\255\220\346\225\260\347\273\204.md" @@ -48,22 +48,22 @@ 首先对于子数组和,我们可以使用「前缀和」的方式,方便快速的得到某个子数组的和。 -对于区间 $[left, right]$,通过 $pre\underline{}sum[right + 1] - prefix\underline{}cnts[left]$ 即可快速求解出区间 $[left, right]$ 的子数组和。 +对于区间 $[left, right]$,通过 $pre\underline{\hspace{0.5em}}sum[right + 1] - prefix\underline{\hspace{0.5em}}cnts[left]$ 即可快速求解出区间 $[left, right]$ 的子数组和。 -此时问题就转变为:是否能找到满足 $i > j$ 且 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$ 两个条件的子数组 $[j, i)$?如果能找到,则找出 $i - j$ 差值最小的作为答案。 +此时问题就转变为:是否能找到满足 $i > j$ 且 $pre\underline{\hspace{0.5em}}sum[i] - pre\underline{\hspace{0.5em}}sum[j] \ge k$ 两个条件的子数组 $[j, i)$?如果能找到,则找出 $i - j$ 差值最小的作为答案。 #### 2. 单调队列优化 对于区间 $[j, i)$ 来说,我们应该尽可能的减少不成立的区间枚举。 -1. 对于某个区间 $[j, i)$ 来说,如果 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$,那么大于 $i$ 的索引值就不用再进行枚举了,不可能比 $i - j$ 的差值更优了。此时我们应该尽可能的向右移动 $j$,从而使得 $i - j$ 更小。 -2. 对于某个区间 $[j, i)$ 来说,如果 $pre\underline{}sum[j] \ge pre\underline{}sum[i]$,对于任何大于等于 $i$ 的索引值 $r$ 来说,$pre\underline{}sum[r] - pre\underline{}sum[i]$ 一定比 $pre\underline{}sum[i] - pre\underline{}sum[j]$ 更小且长度更小,此时 $pre\underline{}sum[j]$ 可以直接忽略掉。 +1. 对于某个区间 $[j, i)$ 来说,如果 $pre\underline{\hspace{0.5em}}sum[i] - pre\underline{\hspace{0.5em}}sum[j] \ge k$,那么大于 $i$ 的索引值就不用再进行枚举了,不可能比 $i - j$ 的差值更优了。此时我们应该尽可能的向右移动 $j$,从而使得 $i - j$ 更小。 +2. 对于某个区间 $[j, i)$ 来说,如果 $pre\underline{\hspace{0.5em}}sum[j] \ge pre\underline{\hspace{0.5em}}sum[i]$,对于任何大于等于 $i$ 的索引值 $r$ 来说,$pre\underline{\hspace{0.5em}}sum[r] - pre\underline{\hspace{0.5em}}sum[i]$ 一定比 $pre\underline{\hspace{0.5em}}sum[i] - pre\underline{\hspace{0.5em}}sum[j]$ 更小且长度更小,此时 $pre\underline{\hspace{0.5em}}sum[j]$ 可以直接忽略掉。 -因此,我们可以使用单调队列来维护单调递增的前缀数组 $pre\underline{}sum$。其中存放了下标 $x:x_0, x_1, …$,满足 $pre\underline{}sum[x_0] < pre\underline{}sum[x_1] < …$ 单调递增。 +因此,我们可以使用单调队列来维护单调递增的前缀数组 $pre\underline{\hspace{0.5em}}sum$。其中存放了下标 $x:x_0, x_1, …$,满足 $pre\underline{\hspace{0.5em}}sum[x_0] < pre\underline{\hspace{0.5em}}sum[x_1] < …$ 单调递增。 1. 使用一重循环遍历位置 $i$,将当前位置 $i$ 存入倒掉队列中。 -2. 对于每一个位置 $i$,如果单调队列不为空,则可以判断其之前存入在单调队列中的 $pre\underline{}sum[j]$ 值,如果 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$,则更新答案,并将 $j$ 从队头位置弹出。直到不再满足 $pre\underline{}sum[i] - pre\underline{}sum[j] \ge k$ 时为止(即 $pre\underline{}sum[i] - pre\underline{}sum[j] < k$)。 -3. 如果队尾 $pre\underline{}sum[j] \ge pre\underline{}sum[i]$,那么说明以后无论如何都不会再考虑 $pre\underline{}sum[j]$ 了,则将其从队尾弹出。 +2. 对于每一个位置 $i$,如果单调队列不为空,则可以判断其之前存入在单调队列中的 $pre\underline{\hspace{0.5em}}sum[j]$ 值,如果 $pre\underline{\hspace{0.5em}}sum[i] - pre\underline{\hspace{0.5em}}sum[j] \ge k$,则更新答案,并将 $j$ 从队头位置弹出。直到不再满足 $pre\underline{\hspace{0.5em}}sum[i] - pre\underline{\hspace{0.5em}}sum[j] \ge k$ 时为止(即 $pre\underline{\hspace{0.5em}}sum[i] - pre\underline{\hspace{0.5em}}sum[j] < k$)。 +3. 如果队尾 $pre\underline{\hspace{0.5em}}sum[j] \ge pre\underline{\hspace{0.5em}}sum[i]$,那么说明以后无论如何都不会再考虑 $pre\underline{\hspace{0.5em}}sum[j]$ 了,则将其从队尾弹出。 4. 最后遍历完返回答案。 ### 思路 1:代码 diff --git "a/Solutions/0868. \344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.md" "b/Solutions/0868. \344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.md" index 9b76fb1c..defbc8ba 100644 --- "a/Solutions/0868. \344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.md" +++ "b/Solutions/0868. \344\272\214\350\277\233\345\210\266\351\227\264\350\267\235.md" @@ -44,9 +44,9 @@ ### 思路 1:遍历 -1. 将正整数 $n$ 转为二进制字符串形式 $bin\underline{}n$。 +1. 将正整数 $n$ 转为二进制字符串形式 $bin\underline{\hspace{0.5em}}n$。 2. 使用变量 $pre$ 记录二进制字符串中上一个 $1$ 的位置,使用变量 $ans$ 存储两个相邻 $1$ 之间的最长距离。 -3. 遍历二进制字符串形式 $bin\underline{}n$ 的每一位,遇到 $1$ 时判断并更新两个相邻 $1$ 之间的最长距离。 +3. 遍历二进制字符串形式 $bin\underline{\hspace{0.5em}}n$ 的每一位,遇到 $1$ 时判断并更新两个相邻 $1$ 之间的最长距离。 4. 遍历完返回两个相邻 $1$ 之间的最长距离,即 $ans$。 ### 思路 1:代码 diff --git "a/Solutions/0892. \344\270\211\347\273\264\345\275\242\344\275\223\347\232\204\350\241\250\351\235\242\347\247\257.md" "b/Solutions/0892. \344\270\211\347\273\264\345\275\242\344\275\223\347\232\204\350\241\250\351\235\242\347\247\257.md" index a936587b..f2b18e2b 100644 --- "a/Solutions/0892. \344\270\211\347\273\264\345\275\242\344\275\223\347\232\204\350\241\250\351\235\242\347\247\257.md" +++ "b/Solutions/0892. \344\270\211\347\273\264\345\275\242\344\275\223\347\232\204\350\241\250\351\235\242\347\247\257.md" @@ -48,10 +48,10 @@ 而每一个正方体所贡献的表面积,可以通过枚举当前正方体前后左右相邻四个方向上的正方体的个数,从而通过判断计算得出。 - 如果当前位置 $(row, col)$ 存在正方体,则正方体在上下位置上起码贡献了 $2$ 的表面积。 -- 如果当前位置 $(row, col)$ 的相邻位置 $(new\underline{}row, new\underline{}col)$ 上不存在正方体,说明当前正方体在该方向为最外侧,则 $(row, col)$ 位置所贡献的表面积为当前位置上的正方体个数,即 $grid[row][col]$。 -- 如果当前位置 $(row, col)$ 的相邻位置 $(new\underline{}row, new\underline{}col)$ 上存在正方体: - - 如果 $grid[row][col] > grid[new\underline{}row][new\underline{}col]$,说明 $grid[row][col]$ 在该方向上底面一部分被 $grid[new\underline{}row][new\underline{}col]$ 遮盖了,则 $(row, col)$ 位置所贡献的表面积为 $grid[row][col] - grid[new_row][new_col]$。 - - 如果 $grid[row][col] \le grid[new\underline{}row][new\underline{}col]$,说明 $grid[row][col]$ 在该方向上完全被 $grid[new\underline{}row][new\underline{}col]$ 遮盖了,则 $(row, col)$ 位置所贡献的表面积为 $0$。 +- 如果当前位置 $(row, col)$ 的相邻位置 $(new\underline{\hspace{0.5em}}row, new\underline{\hspace{0.5em}}col)$ 上不存在正方体,说明当前正方体在该方向为最外侧,则 $(row, col)$ 位置所贡献的表面积为当前位置上的正方体个数,即 $grid[row][col]$。 +- 如果当前位置 $(row, col)$ 的相邻位置 $(new\underline{\hspace{0.5em}}row, new\underline{\hspace{0.5em}}col)$ 上存在正方体: + - 如果 $grid[row][col] > grid[new\underline{\hspace{0.5em}}row][new\underline{\hspace{0.5em}}col]$,说明 $grid[row][col]$ 在该方向上底面一部分被 $grid[new\underline{\hspace{0.5em}}row][new\underline{\hspace{0.5em}}col]$ 遮盖了,则 $(row, col)$ 位置所贡献的表面积为 $grid[row][col] - grid[new_row][new_col]$。 + - 如果 $grid[row][col] \le grid[new\underline{\hspace{0.5em}}row][new\underline{\hspace{0.5em}}col]$,说明 $grid[row][col]$ 在该方向上完全被 $grid[new\underline{\hspace{0.5em}}row][new\underline{\hspace{0.5em}}col]$ 遮盖了,则 $(row, col)$ 位置所贡献的表面积为 $0$。 ### 思路 1:代码 diff --git "a/Solutions/0900. RLE \350\277\255\344\273\243\345\231\250.md" "b/Solutions/0900. RLE \350\277\255\344\273\243\345\231\250.md" index d806bc71..5b0aa72f 100644 --- "a/Solutions/0900. RLE \350\277\255\344\273\243\345\231\250.md" +++ "b/Solutions/0900. RLE \350\277\255\344\273\243\345\231\250.md" @@ -56,12 +56,12 @@ rLEIterator.next(2); // 耗去序列的 2 个项,返回 -1。 这是由于第 1. 初始化时: 1. 保存数组 $encoding$ 作为成员变量。 2. 保存当前位置 $index$,表示当前迭代器指向元素 $encoding[index + 1]$。初始化赋值为 $0$。 - 3. 保存当前指向元素 $encoding[index + 1]$ 已经被删除的元素个数 $d\underline{}cnt$。初始化赋值为 $0$。 + 3. 保存当前指向元素 $encoding[index + 1]$ 已经被删除的元素个数 $d\underline{\hspace{0.5em}}cnt$。初始化赋值为 $0$。 2. 调用 `next(n)` 时: 1. 对于当前元素,先判断当前位置是否超出 $encoding$ 范围,超过则直接返回 $-1$。 - 2. 如果未超过,再判断当前元素剩余个数 $encoding[index] - d\underline{}cnt$ 是否小于 $n$ 个。 + 2. 如果未超过,再判断当前元素剩余个数 $encoding[index] - d\underline{\hspace{0.5em}}cnt$ 是否小于 $n$ 个。 1. 如果小于 $n$ 个,则删除当前元素剩余所有个数,并指向下一位置继续删除剩余元素。 - 2. 如果等于大于等于 $n$ 个,则令当前指向元素 $encoding[index + 1]$ 已经被删除的元素个数 $d\underline{}cnt$ 加上 $n$。 + 2. 如果等于大于等于 $n$ 个,则令当前指向元素 $encoding[index + 1]$ 已经被删除的元素个数 $d\underline{\hspace{0.5em}}cnt$ 加上 $n$。 ### 思路 1:代码 diff --git "a/Solutions/0912. \346\216\222\345\272\217\346\225\260\347\273\204.md" "b/Solutions/0912. \346\216\222\345\272\217\346\225\260\347\273\204.md" index afb94090..c8840726 100644 --- "a/Solutions/0912. \346\216\222\345\272\217\346\225\260\347\273\204.md" +++ "b/Solutions/0912. \346\216\222\345\272\217\346\225\260\347\273\204.md" @@ -97,12 +97,12 @@ class Solution: 1. 初始状态下,无已排序区间,未排序区间为 $[0, n - 1]$。 2. 第 $1$ 趟选择: - 1. 遍历未排序区间 $[0, n - 1]$,使用变量 $min\underline{}i$ 记录区间中值最小的元素位置。 - 2. 将 $min\underline{}i$ 与下标为 $0$ 处的元素交换位置。如果下标为 $0$ 处元素就是值最小的元素位置,则不用交换。 + 1. 遍历未排序区间 $[0, n - 1]$,使用变量 $min\underline{\hspace{0.5em}}i$ 记录区间中值最小的元素位置。 + 2. 将 $min\underline{\hspace{0.5em}}i$ 与下标为 $0$ 处的元素交换位置。如果下标为 $0$ 处元素就是值最小的元素位置,则不用交换。 3. 此时,$[0, 0]$ 为已排序区间,$[1, n - 1]$(总共 $n - 1$ 个元素)为未排序区间。 3. 第 $2$ 趟选择: - 1. 遍历未排序区间 $[1, n - 1]$,使用变量 $min\underline{}i$ 记录区间中值最小的元素位置。 - 2. 将 $min\underline{}i$ 与下标为 $1$ 处的元素交换位置。如果下标为 $1$ 处元素就是值最小的元素位置,则不用交换。 + 1. 遍历未排序区间 $[1, n - 1]$,使用变量 $min\underline{\hspace{0.5em}}i$ 记录区间中值最小的元素位置。 + 2. 将 $min\underline{\hspace{0.5em}}i$ 与下标为 $1$ 处的元素交换位置。如果下标为 $1$ 处元素就是值最小的元素位置,则不用交换。 3. 此时,$[0, 1]$ 为已排序区间,$[2, n - 1]$(总共 $n - 2$ 个元素)为未排序区间。 4. 依次类推,对剩余未排序区间重复上述选择过程,直到所有元素都划分到已排序区间,排序结束。 @@ -231,12 +231,12 @@ class Solution: 假设数组的元素个数为 $n$ 个,则归并排序的算法步骤如下: 1. **分解过程**:先递归地将当前数组平均分成两半,直到子数组长度为 $1$。 - 1. 找到数组中心位置 $mid$,从中心位置将数组分成左右两个子数组 $left\underline{}nums$、$right\underline{}nums$。 - 2. 对左右两个子数组 $left\underline{}nums$、$right\underline{}nums$ 分别进行递归分解。 + 1. 找到数组中心位置 $mid$,从中心位置将数组分成左右两个子数组 $left\underline{\hspace{0.5em}}nums$、$right\underline{\hspace{0.5em}}nums$。 + 2. 对左右两个子数组 $left\underline{\hspace{0.5em}}nums$、$right\underline{\hspace{0.5em}}nums$ 分别进行递归分解。 3. 最终将数组分解为 $n$ 个长度均为 $1$ 的有序子数组。 2. **归并过程**:从长度为 $1$ 的有序子数组开始,依次将有序数组两两合并,直到合并成一个长度为 $n$ 的有序数组。 1. 使用数组变量 $nums$ 存放合并后的有序数组。 - 2. 使用两个指针 $left\underline{}i$、$right\underline{}i$ 分别指向两个有序子数组 $left\underline{}nums$、$right\underline{}nums$ 的开始位置。 + 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$ 的开始位置。 3. 比较两个指针指向的元素,将两个有序子数组中较小元素依次存入到结果数组 $nums$ 中,并将指针移动到下一位置。 4. 重复步骤 $3$,直到某一指针到达子数组末尾。 5. 将另一个子数组中的剩余元素存入到结果数组 $nums$ 中。 @@ -440,15 +440,15 @@ class Solution: 假设数组的元素个数为 $n$ 个,则计数排序的算法步骤如下: -1. **计算排序范围**:遍历数组,找出待排序序列中最大值元素 $nums\underline{}max$ 和最小值元素 $nums\underline{}min$,计算出排序范围为 $nums\underline{}max - nums\underline{}min + 1$。 +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$。 2. **定义计数数组**:定义一个大小为排序范围的计数数组 $counts$,用于统计每个元素的出现次数。其中: - 1. 数组的索引值 $num - nums\underline{}min$ 表示元素的值为 $num$。 - 2. 数组的值 $counts[num - nums\underline{}min]$ 表示元素 $num$ 的出现次数。 + 1. 数组的索引值 $num - nums\underline{\hspace{0.5em}}min$ 表示元素的值为 $num$。 + 2. 数组的值 $counts[num - nums\underline{\hspace{0.5em}}min]$ 表示元素 $num$ 的出现次数。 -3. **对数组元素进行计数统计**:遍历待排序数组 $nums$,对每个元素在计数数组中进行计数,即将待排序数组中「每个元素值减去最小值」作为索引,将「对计数数组中的值」加 $1$,即令 $counts[num - nums\underline{}min]$ 加 $1$。 -4. **生成累积计数数组**:从 $counts$ 中的第 $1$ 个元素开始,每一项累家前一项和。此时 $counts[num - nums\underline{}min]$ 表示值为 $num$ 的元素在排序数组中最后一次出现的位置。 +3. **对数组元素进行计数统计**:遍历待排序数组 $nums$,对每个元素在计数数组中进行计数,即将待排序数组中「每个元素值减去最小值」作为索引,将「对计数数组中的值」加 $1$,即令 $counts[num - nums\underline{\hspace{0.5em}}min]$ 加 $1$。 +4. **生成累积计数数组**:从 $counts$ 中的第 $1$ 个元素开始,每一项累家前一项和。此时 $counts[num - nums\underline{\hspace{0.5em}}min]$ 表示值为 $num$ 的元素在排序数组中最后一次出现的位置。 5. **逆序填充目标数组**:逆序遍历数组 $nums$,将每个元素 $num$ 填入正确位置。 - 6. 将其填充到结果数组 $res$ 的索引 $counts[num - nums\underline{}min]$ 处。 + 6. 将其填充到结果数组 $res$ 的索引 $counts[num - nums\underline{\hspace{0.5em}}min]$ 处。 7. 放入后,令累积计数数组中对应索引减 $1$,从而得到下个元素 $num$ 的放置位置。 ### 思路 8:代码 diff --git "a/Solutions/0925. \351\225\277\346\214\211\351\224\256\345\205\245.md" "b/Solutions/0925. \351\225\277\346\214\211\351\224\256\345\205\245.md" index e7f05d7d..27f8eaf0 100644 --- "a/Solutions/0925. \351\225\277\346\214\211\351\224\256\345\205\245.md" +++ "b/Solutions/0925. \351\225\277\346\214\211\351\224\256\345\205\245.md" @@ -44,14 +44,14 @@ 这道题目的意思是在 $typed$ 里边匹配 $name$,同时要考虑字符重复问题,以及不匹配的情况。可以使用分离双指针来做。具体做法如下: -1. 使用两个指针 $left\underline{}1$、$left\underline{}2$,$left\underline{}1$ 指向字符串 $name$ 开始位置,$left\underline{}2$ 指向字符串 $type$ 开始位置。 -2. 如果 $name[left\underline{}1] == name[left\underline{}2]$,则将 $left\underline{}1$、$left\underline{}2$ 同时右移。 -3. 如果 $nmae[left\underline{}1] \ne name[left\underline{}2]$,则: - 1. 如果 $typed[left\underline{}2]$ 和前一个位置元素 $typed[left\underline{}2 - 1]$ 相等,则说明出现了重复元素,将 $left\underline{}2$ 右移,过滤重复元素。 - 2. 如果 $typed[left\underline{}2]$ 和前一个位置元素 $typed[left\underline{}2 - 1]$ 不等,则说明出现了多余元素,不匹配。直接返回 `False` 即可。 - -4. 当 $left\underline{}1 == len(name)$ 或者 $left\underline{}2 == len(typed)$ 时跳出循环。然后过滤掉 $typed$ 末尾的重复元素。 -5. 最后判断,如果 $left\underline{}1 == len(name)$ 并且 $left\underline{}2 == len(typed)$,则说明匹配,返回 `True`,否则返回 `False`。 +1. 使用两个指针 $left\underline{\hspace{0.5em}}1$、$left\underline{\hspace{0.5em}}2$,$left\underline{\hspace{0.5em}}1$ 指向字符串 $name$ 开始位置,$left\underline{\hspace{0.5em}}2$ 指向字符串 $type$ 开始位置。 +2. 如果 $name[left\underline{\hspace{0.5em}}1] == name[left\underline{\hspace{0.5em}}2]$,则将 $left\underline{\hspace{0.5em}}1$、$left\underline{\hspace{0.5em}}2$ 同时右移。 +3. 如果 $nmae[left\underline{\hspace{0.5em}}1] \ne name[left\underline{\hspace{0.5em}}2]$,则: + 1. 如果 $typed[left\underline{\hspace{0.5em}}2]$ 和前一个位置元素 $typed[left\underline{\hspace{0.5em}}2 - 1]$ 相等,则说明出现了重复元素,将 $left\underline{\hspace{0.5em}}2$ 右移,过滤重复元素。 + 2. 如果 $typed[left\underline{\hspace{0.5em}}2]$ 和前一个位置元素 $typed[left\underline{\hspace{0.5em}}2 - 1]$ 不等,则说明出现了多余元素,不匹配。直接返回 `False` 即可。 + +4. 当 $left\underline{\hspace{0.5em}}1 == len(name)$ 或者 $left\underline{\hspace{0.5em}}2 == len(typed)$ 时跳出循环。然后过滤掉 $typed$ 末尾的重复元素。 +5. 最后判断,如果 $left\underline{\hspace{0.5em}}1 == len(name)$ 并且 $left\underline{\hspace{0.5em}}2 == len(typed)$,则说明匹配,返回 `True`,否则返回 `False`。 ### 思路 1:代码 diff --git "a/Solutions/0995. K \350\277\236\347\273\255\344\275\215\347\232\204\346\234\200\345\260\217\347\277\273\350\275\254\346\254\241\346\225\260.md" "b/Solutions/0995. K \350\277\236\347\273\255\344\275\215\347\232\204\346\234\200\345\260\217\347\277\273\350\275\254\346\254\241\346\225\260.md" index c28e4509..fa49023c 100644 --- "a/Solutions/0995. K \350\277\236\347\273\255\344\275\215\347\232\204\346\234\200\345\260\217\347\277\273\350\275\254\346\254\241\346\225\260.md" +++ "b/Solutions/0995. K \350\277\236\347\273\255\344\275\215\347\232\204\346\234\200\345\260\217\347\277\273\350\275\254\346\254\241\346\225\260.md" @@ -55,21 +55,21 @@ 同时如果我们知道了前面 $k - 1$ 个元素的翻转次数就可以直接修改 $nums[i]$ 了。 -我们使用 $flip\underline{}count$ 记录第 $i$ 个元素之前 $k - 1$ 个位置总共被反转了多少次,或者 $flip\underline{}count$ 是大小为 $k - 1$ 的滑动窗口。 +我们使用 $flip\underline{\hspace{0.5em}}count$ 记录第 $i$ 个元素之前 $k - 1$ 个位置总共被反转了多少次,或者 $flip\underline{\hspace{0.5em}}count$ 是大小为 $k - 1$ 的滑动窗口。 - 如果前面第 $k - 1$ 个元素翻转了奇数次,则如果 $nums[i] == 1$,则 $nums[i]$ 也被翻转成了 $0$,需要再翻转 $1$ 次。 - 如果前面第 $k - 1$ 个元素翻转了偶数次,则如果 $nums[i] == 0$,则 $nums[i]$ 也被翻转成为了 $0$,需要再翻转 $1$ 次。 这两句写成判断语句可以写为:`if (flip_count + nums[i]) % 2 == 0:`。 -因为 $0 <= nums[i] <= 1$,所以我们可以用 $0$ 和 $1$ 以外的数,比如 $2$ 来标记第 $i$ 个元素发生了翻转,即 `nums[i] = 2`。这样在遍历到第 $i$ 个元素时,如果有 $nums[i - k] == 2$,则说明 $nums[i - k]$ 发生了翻转。同时根据 $flip\underline{}count$ 和 $nums[i]$ 来判断第 $i$ 位是否需要进行翻转。 +因为 $0 <= nums[i] <= 1$,所以我们可以用 $0$ 和 $1$ 以外的数,比如 $2$ 来标记第 $i$ 个元素发生了翻转,即 `nums[i] = 2`。这样在遍历到第 $i$ 个元素时,如果有 $nums[i - k] == 2$,则说明 $nums[i - k]$ 发生了翻转。同时根据 $flip\underline{\hspace{0.5em}}count$ 和 $nums[i]$ 来判断第 $i$ 位是否需要进行翻转。 整个算法的具体步骤如下: -- 使用 $res$ 记录最小翻转次数。使用 $flip\underline{}count$ 记录窗口内前 $k - 1 $ 位元素的翻转次数。 +- 使用 $res$ 记录最小翻转次数。使用 $flip\underline{\hspace{0.5em}}count$ 记录窗口内前 $k - 1 $ 位元素的翻转次数。 - 遍历数组 $nums$,对于第 $i$ 位元素: - 如果 $i - k >= 0$,并且 $nums[i - k] == 2$,需要缩小窗口,将翻转次数减一。(此时窗口范围为 $[i - k + 1, i - 1]$)。 - - 如果 $(flip\underline{}count + nums[i]) \mod 2 == 0$,则说明 $nums[i]$ 还需要再翻转一次,将 $nums[i]$ 标记为 $2$,同时更新窗口内翻转次数 $flip\underline{}count$ 和答案最小翻转次数 $ans$。 + - 如果 $(flip\underline{\hspace{0.5em}}count + nums[i]) \mod 2 == 0$,则说明 $nums[i]$ 还需要再翻转一次,将 $nums[i]$ 标记为 $2$,同时更新窗口内翻转次数 $flip\underline{\hspace{0.5em}}count$ 和答案最小翻转次数 $ans$。 - 遍历完之后,返回 $res$。 ### 思路 1:代码 diff --git "a/Solutions/0999. \345\217\257\344\273\245\350\242\253\344\270\200\346\255\245\346\215\225\350\216\267\347\232\204\346\243\213\345\255\220\346\225\260.md" "b/Solutions/0999. \345\217\257\344\273\245\350\242\253\344\270\200\346\255\245\346\215\225\350\216\267\347\232\204\346\243\213\345\255\220\346\225\260.md" index 5394446c..465dc0ba 100644 --- "a/Solutions/0999. \345\217\257\344\273\245\350\242\253\344\270\200\346\255\245\346\215\225\350\216\267\347\232\204\346\243\213\345\255\220\346\225\260.md" +++ "b/Solutions/0999. \345\217\257\344\273\245\350\242\253\344\270\200\346\255\245\346\215\225\350\216\267\347\232\204\346\243\213\345\255\220\346\225\260.md" @@ -51,7 +51,7 @@ ### 思路 1:模拟 -1. 双重循环遍历确定白色车的位置 $(pos\underline{}i,poss\underline{}j)$。 +1. 双重循环遍历确定白色车的位置 $(pos\underline{\hspace{0.5em}}i,poss\underline{\hspace{0.5em}}j)$。 2. 让车向上、下、左、右四个方向进行移动,直到超出边界 / 碰到白色象 / 碰到卒为止。使用计数器 $cnt$ 记录捕获的卒的数量。 3. 返回答案 $cnt$。 diff --git "a/Solutions/1004. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 III.md" "b/Solutions/1004. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 III.md" index 26bde514..39bb3c93 100644 --- "a/Solutions/1004. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 III.md" +++ "b/Solutions/1004. \346\234\200\345\244\247\350\277\236\347\273\2551\347\232\204\344\270\252\346\225\260 III.md" @@ -43,10 +43,10 @@ ### 思路 1:滑动窗口(不定长度) -1. 使用两个指针 $left$、$right$ 指向数组开始位置。使用 $max\underline{}count$ 来维护仅包含 $1$ 的最长连续子数组的长度。 +1. 使用两个指针 $left$、$right$ 指向数组开始位置。使用 $max\underline{\hspace{0.5em}}count$ 来维护仅包含 $1$ 的最长连续子数组的长度。 2. 不断右移 $right$ 指针,扩大滑动窗口范围,并统计窗口内 $0$ 元素的个数。 -3. 直到 $0$ 元素的个数超过 $k$ 时将 $left$ 右移,缩小滑动窗口范围,并减小 $0$ 元素的个数,同时维护 $max\underline{}count$。 -4. 最后输出最长连续子数组的长度 $max\underline{}count$。 +3. 直到 $0$ 元素的个数超过 $k$ 时将 $left$ 右移,缩小滑动窗口范围,并减小 $0$ 元素的个数,同时维护 $max\underline{\hspace{0.5em}}count$。 +4. 最后输出最长连续子数组的长度 $max\underline{\hspace{0.5em}}count$。 ### 思路 1:代码 diff --git "a/Solutions/1049. \346\234\200\345\220\216\344\270\200\345\235\227\347\237\263\345\244\264\347\232\204\351\207\215\351\207\217 II.md" "b/Solutions/1049. \346\234\200\345\220\216\344\270\200\345\235\227\347\237\263\345\244\264\347\232\204\351\207\215\351\207\217 II.md" index 1e8b780d..3eb5250f 100644 --- "a/Solutions/1049. \346\234\200\345\220\216\344\270\200\345\235\227\347\237\263\345\244\264\347\232\204\351\207\215\351\207\217 II.md" +++ "b/Solutions/1049. \346\234\200\345\220\216\344\270\200\345\235\227\347\237\263\345\244\264\347\232\204\351\207\215\351\207\217 II.md" @@ -54,8 +54,8 @@ 进一步可以变为:「0-1 背包问题」。 -1. 假设石头总重量和为 $sum$,将一堆石头放进载重上限为 $sum / 2$ 的背包中,获得的最大价值为 $max\underline{}weight$(即其中一堆石子的重量)。另一堆石子的重量为 $sum - max\underline{}weight$。 -2. 则两者的差值为 $sum - 2 \times max\underline{}weight$,即为答案。 +1. 假设石头总重量和为 $sum$,将一堆石头放进载重上限为 $sum / 2$ 的背包中,获得的最大价值为 $max\underline{\hspace{0.5em}}weight$(即其中一堆石子的重量)。另一堆石子的重量为 $sum - max\underline{\hspace{0.5em}}weight$。 +2. 则两者的差值为 $sum - 2 \times max\underline{\hspace{0.5em}}weight$,即为答案。 ###### 1. 划分阶段 diff --git "a/Solutions/1052. \347\210\261\347\224\237\346\260\224\347\232\204\344\271\246\345\272\227\350\200\201\346\235\277.md" "b/Solutions/1052. \347\210\261\347\224\237\346\260\224\347\232\204\344\271\246\345\272\227\350\200\201\346\235\277.md" index 1e1a2072..529c7352 100644 --- "a/Solutions/1052. \347\210\261\347\224\237\346\260\224\347\232\204\344\271\246\345\272\227\350\200\201\346\235\277.md" +++ "b/Solutions/1052. \347\210\261\347\224\237\346\260\224\347\232\204\344\271\246\345\272\227\350\200\201\346\235\277.md" @@ -50,9 +50,9 @@ 固定长度的滑动窗口题目。我们可以维护一个窗口大小为 $minutes$ 的滑动窗口。使用 $window_count$ 记录当前窗口内生气的顾客人数。然后滑动求出窗口中最大顾客数,然后累加上老板未生气时的顾客数,就是答案。具体做法如下: -1. $ans$ 用来维护答案数目。$window\underline{}count$ 用来维护窗口中生气的顾客人数。 +1. $ans$ 用来维护答案数目。$window\underline{\hspace{0.5em}}count$ 用来维护窗口中生气的顾客人数。 2. $left$ 、$right$ 都指向序列的第一个元素,即:`left = 0`,`right = 0`。 -3. 如果书店老板生气,则将这一分钟的顾客数量加入到 $window\underline{}count$ 中,然后向右移动 $right$。 +3. 如果书店老板生气,则将这一分钟的顾客数量加入到 $window\underline{\hspace{0.5em}}count$ 中,然后向右移动 $right$。 4. 当窗口元素个数大于 $minutes$ 时,即:$right - left + 1 > count$ 时,如果最左侧边界老板处于生气状态,则向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为小于 $minutes$。 5. 重复 $3 \sim 4$ 步,直到 $right$ 到达数组末尾。 6. 然后累加上老板未生气时的顾客数,最后输出答案。 diff --git "a/Solutions/1103. \345\210\206\347\263\226\346\236\234 II.md" "b/Solutions/1103. \345\210\206\347\263\226\346\236\234 II.md" index 37f08e01..dd879a20 100644 --- "a/Solutions/1103. \345\210\206\347\263\226\346\236\234 II.md" +++ "b/Solutions/1103. \345\210\206\347\263\226\346\236\234 II.md" @@ -9,7 +9,7 @@ ## 题目大意 -**描述**:给定一个整数 $candies$,代表糖果的数量。再给定一个整数 $num\underline{}people$,代表小朋友的数量。 +**描述**:给定一个整数 $candies$,代表糖果的数量。再给定一个整数 $num\underline{\hspace{0.5em}}people$,代表小朋友的数量。 现在开始分糖果,给第 $1$ 个小朋友分 $1$ 颗糖果,第 $2$ 个小朋友分 $2$ 颗糖果,以此类推,直到最后一个小朋友分 $n$ 颗糖果。 @@ -19,12 +19,12 @@ > 注意:如果我们手中剩下的糖果数不够(小于等于前一次发的糖果数),则将剩下的糖果全部发给当前的小朋友。 -**要求**:返回一个长度为 $num\underline{}people$、元素之和为 $candies$ 的数组,以表示糖果的最终分发情况(即 $ans[i]$ 表示第 $i$ 个小朋友分到的糖果数)。 +**要求**:返回一个长度为 $num\underline{\hspace{0.5em}}people$、元素之和为 $candies$ 的数组,以表示糖果的最终分发情况(即 $ans[i]$ 表示第 $i$ 个小朋友分到的糖果数)。 **说明**: - $1 \le candies \le 10^9$。 -- $1 \le num\underline{}people \le 1000$。 +- $1 \le num\underline{\hspace{0.5em}}people \le 1000$。 **示例**: diff --git "a/Solutions/1110. \345\210\240\347\202\271\346\210\220\346\236\227.md" "b/Solutions/1110. \345\210\240\347\202\271\346\210\220\346\236\227.md" index de2d2f16..af57e3fe 100644 --- "a/Solutions/1110. \345\210\240\347\202\271\346\210\220\346\236\227.md" +++ "b/Solutions/1110. \345\210\240\347\202\271\346\210\220\346\236\227.md" @@ -11,7 +11,7 @@ **描述**:给定二叉树的根节点 $root$,树上每个节点都有一个不同的值。 -如果节点值在 $to\underline{}delete$ 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。 +如果节点值在 $to\underline{\hspace{0.5em}}delete$ 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。 **要求**:返回森林中的每棵树。你可以按任意顺序组织答案。 @@ -19,8 +19,8 @@ - 树中的节点数最大为 $1000$。 - 每个节点都有一个介于 $1$ 到 $1000$ 之间的值,且各不相同。 -- $to\underline{}delete.length \le 1000$。 -- $to\underline{}delete$ 包含一些从 $1$ 到 $1000$、各不相同的值。 +- $to\underline{\hspace{0.5em}}delete.length \le 1000$。 +- $to\underline{\hspace{0.5em}}delete$ 包含一些从 $1$ 到 $1000$、各不相同的值。 **示例**: @@ -44,7 +44,7 @@ ### 思路 1:深度优先搜索 -将待删除节点数组 $to\underline{}delete$ 转为集合 $deletes$,则每次能以 $O(1)$ 的时间复杂度判断节点值是否在待删除节点数组中。 +将待删除节点数组 $to\underline{\hspace{0.5em}}delete$ 转为集合 $deletes$,则每次能以 $O(1)$ 的时间复杂度判断节点值是否在待删除节点数组中。 如果当前节点值在待删除节点数组中,则删除当前节点后,我们还需要判断其左右子节点是否也在待删除节点数组中。 diff --git "a/Solutions/1151. \346\234\200\345\260\221\344\272\244\346\215\242\346\254\241\346\225\260\346\235\245\347\273\204\345\220\210\346\211\200\346\234\211\347\232\204 1.md" "b/Solutions/1151. \346\234\200\345\260\221\344\272\244\346\215\242\346\254\241\346\225\260\346\235\245\347\273\204\345\220\210\346\211\200\346\234\211\347\232\204 1.md" index df34446e..f2016522 100644 --- "a/Solutions/1151. \346\234\200\345\260\221\344\272\244\346\215\242\346\254\241\346\225\260\346\235\245\347\273\204\345\220\210\346\211\200\346\234\211\347\232\204 1.md" +++ "b/Solutions/1151. \346\234\200\345\260\221\344\272\244\346\215\242\346\254\241\346\225\260\346\235\245\347\273\204\345\220\210\346\211\200\346\234\211\347\232\204 1.md" @@ -50,12 +50,12 @@ 求最少交换次数,也就是求滑动窗口中最少的 $0$ 的个数。具体做法如下: -1. 统计 $1$ 的个数,并设置为窗口长度 $window\underline{}size$。使用 $window\underline{}count$ 维护窗口中 $0$ 的个数。使用 $ans$ 维护窗口中最少的 $0$ 的个数,也可以叫做最少交换次数。 -2. 如果 $window\underline{}size$ 为 $0$,则说明不用交换,直接返回 $0$。 +1. 统计 $1$ 的个数,并设置为窗口长度 $window\underline{\hspace{0.5em}}size$。使用 $window\underline{\hspace{0.5em}}count$ 维护窗口中 $0$ 的个数。使用 $ans$ 维护窗口中最少的 $0$ 的个数,也可以叫做最少交换次数。 +2. 如果 $window\underline{\hspace{0.5em}}size$ 为 $0$,则说明不用交换,直接返回 $0$。 3. 使用两个指针 $left$、$right$。$left$、$right$ 都指向数组的第一个元素,即:`left = 0`,`right = 0`。 4. 如果 $data[right] == 0$,则更新窗口中 $0$ 的个数,即 `window_count += 1`。然后向右移动 $right$。 -5. 当窗口元素个数为 $window\underline{}size$ 时,即:$right - left + 1 \ge window\underline{}size$ 时,更新窗口中最少的 $0$ 的个数。 -6. 然后如果左侧 $data[left] == 0$,则更新窗口中 $0$ 的个数,即 `window_count -= 1`。然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{}size$。 +5. 当窗口元素个数为 $window\underline{\hspace{0.5em}}size$ 时,即:$right - left + 1 \ge window\underline{\hspace{0.5em}}size$ 时,更新窗口中最少的 $0$ 的个数。 +6. 然后如果左侧 $data[left] == 0$,则更新窗口中 $0$ 的个数,即 `window_count -= 1`。然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $window\underline{\hspace{0.5em}}size$。 7. 重复 4 ~ 6 步,直到 $right$ 到达数组末尾。返回答案 $ans$。 ### 思路 1:代码 diff --git "a/Solutions/1161. \346\234\200\345\244\247\345\261\202\345\206\205\345\205\203\347\264\240\345\222\214.md" "b/Solutions/1161. \346\234\200\345\244\247\345\261\202\345\206\205\345\205\203\347\264\240\345\222\214.md" index d838bfc3..1500f6b3 100644 --- "a/Solutions/1161. \346\234\200\345\244\247\345\261\202\345\206\205\345\205\203\347\264\240\345\222\214.md" +++ "b/Solutions/1161. \346\234\200\345\244\247\345\261\202\345\206\205\345\205\203\347\264\240\345\222\214.md" @@ -46,8 +46,8 @@ ### 思路 1:二叉树的层序遍历 1. 利用广度优先搜索,在二叉树的层序遍历的基础上,统计每一层节点和,并存入数组 $levels$ 中。 -2. 遍历 $levels$ 数组,从 $levels$ 数组中找到最大层和 $max\underline{}sum$。 -3. 再次遍历 $levels$ 数组,找出等于最大层和 $max\underline{}sum$ 的那一层,并返回该层序号。 +2. 遍历 $levels$ 数组,从 $levels$ 数组中找到最大层和 $max\underline{\hspace{0.5em}}sum$。 +3. 再次遍历 $levels$ 数组,找出等于最大层和 $max\underline{\hspace{0.5em}}sum$ 的那一层,并返回该层序号。 ### 思路 1:代码 diff --git "a/Solutions/1176. \345\201\245\350\272\253\350\256\241\345\210\222\350\257\204\344\274\260.md" "b/Solutions/1176. \345\201\245\350\272\253\350\256\241\345\210\222\350\257\204\344\274\260.md" index c1360d71..f6e0a309 100644 --- "a/Solutions/1176. \345\201\245\350\272\253\350\256\241\345\210\222\350\257\204\344\274\260.md" +++ "b/Solutions/1176. \345\201\245\350\272\253\350\256\241\345\210\222\350\257\204\344\274\260.md" @@ -49,7 +49,7 @@ 固定长度为 $k$ 的滑动窗口题目。具体做法如下: -1. $score$ 用来维护得分情况,初始值为 $0$。$window\underline{}sum$ 用来维护窗口中卡路里总量。 +1. $score$ 用来维护得分情况,初始值为 $0$。$window\underline{\hspace{0.5em}}sum$ 用来维护窗口中卡路里总量。 2. $left$ 、$right$ 都指向数组的第一个元素,即:`left = 0`,`right = 0`。 3. 向右移动 $right$,先将 $k$ 个元素填入窗口中。 4. 当窗口元素个数为 $k$ 时,即:$right - left + 1 \ge k$ 时,计算窗口内的卡路里总量,并判断和 $upper$、$lower$ 的关系。同时维护得分情况。 diff --git "a/Solutions/1208. \345\260\275\345\217\257\350\203\275\344\275\277\345\255\227\347\254\246\344\270\262\347\233\270\347\255\211.md" "b/Solutions/1208. \345\260\275\345\217\257\350\203\275\344\275\277\345\255\227\347\254\246\344\270\262\347\233\270\347\255\211.md" index 3868494d..89280181 100644 --- "a/Solutions/1208. \345\260\275\345\217\257\350\203\275\344\275\277\345\255\227\347\254\246\344\270\262\347\233\270\347\255\211.md" +++ "b/Solutions/1208. \345\260\275\345\217\257\350\203\275\344\275\277\345\255\227\347\254\246\344\270\262\347\233\270\347\255\211.md" @@ -41,14 +41,14 @@ ### 思路 1:滑动窗口 -维护一个滑动窗口 $window\underline{}sum$ 用于记录窗口内的开销总和,保证窗口内的开销总和小于等于 $maxCost$。使用 $ans$ 记录可以转化的最大长度。具体做法如下: +维护一个滑动窗口 $window\underline{\hspace{0.5em}}sum$ 用于记录窗口内的开销总和,保证窗口内的开销总和小于等于 $maxCost$。使用 $ans$ 记录可以转化的最大长度。具体做法如下: 使用两个指针 $left$、$right$。分别指向滑动窗口的左右边界,保证窗口内所有元素转化开销总和小于等于 $maxCost$。 - 先统计出 $s$ 中第 $i$ 个字符变为 $t$ 的第 $i$ 个字符的开销,用数组 $costs$ 保存。 - 一开始,$left$、$right$ 都指向 $0$。 - 将最右侧字符的转变开销填入窗口中,向右移动 $right$。 -- 直到窗口内开销总和 $window\underline{}sum$ 大于 $maxCost$。则不断右移 $left$,缩小窗口长度。直到 $window\underline{}sum \le maxCost$ 时,更新可以转换的最大长度 $ans$。 +- 直到窗口内开销总和 $window\underline{\hspace{0.5em}}sum$ 大于 $maxCost$。则不断右移 $left$,缩小窗口长度。直到 $window\underline{\hspace{0.5em}}sum \le maxCost$ 时,更新可以转换的最大长度 $ans$。 - 向右移动 $right$,直到 $right \ge len(s)$ 为止。 - 输出答案 $ans$。 diff --git "a/Solutions/1229. \345\256\211\346\216\222\344\274\232\350\256\256\346\227\245\347\250\213.md" "b/Solutions/1229. \345\256\211\346\216\222\344\274\232\350\256\256\346\227\245\347\250\213.md" index 94cd6e0a..3ebc139a 100644 --- "a/Solutions/1229. \345\256\211\346\216\222\344\274\232\350\256\256\346\227\245\347\250\213.md" +++ "b/Solutions/1229. \345\256\211\346\216\222\344\274\232\350\256\256\346\227\245\347\250\213.md" @@ -49,12 +49,12 @@ 题目保证了同一个人的空闲时间不会出现交叠。那么可以先直接对两个客户的空间时间表按照开始时间从小到大排序。然后使用分离双指针来遍历两个数组,求出重合部分,并判断重合区间是否大于等于 $duration$。具体做法如下: 1. 先对两个数组排序。 -2. 然后使用两个指针 $left\underline{}1$、$left\underline{}2$。$left\underline{}1$ 指向第一个数组开始位置,$left\underline{}2$ 指向第二个数组开始位置。 +2. 然后使用两个指针 $left\underline{\hspace{0.5em}}1$、$left\underline{\hspace{0.5em}}2$。$left\underline{\hspace{0.5em}}1$ 指向第一个数组开始位置,$left\underline{\hspace{0.5em}}2$ 指向第二个数组开始位置。 3. 遍历两个数组。计算当前两个空闲时间区间的重叠范围。 1. 如果重叠范围大于等于 $duration$,直接返回当前重叠范围开始时间和会议结束时间,即 $[start, start + duration]$,$start$ 为重叠范围开始时间。 - 2. 如果第一个客户的空闲结束时间小于第二个客户的空闲结束时间,则令 $left\underline{}1$ 右移,即 `left_1 += 1`,继续比较重叠范围。 - 3. 如果第一个客户的空闲结束时间大于等于第二个客户的空闲结束时间,则令 $left\underline{}2$ 右移,即 `left_2 += 1`,继续比较重叠范围。 -4. 直到 $left\underline{}1 == len(slots1)$ 或者 $left\underline{}2 == len(slots2)$ 时跳出循环,返回空数组 $[]$。 + 2. 如果第一个客户的空闲结束时间小于第二个客户的空闲结束时间,则令 $left\underline{\hspace{0.5em}}1$ 右移,即 `left_1 += 1`,继续比较重叠范围。 + 3. 如果第一个客户的空闲结束时间大于等于第二个客户的空闲结束时间,则令 $left\underline{\hspace{0.5em}}2$ 右移,即 `left_2 += 1`,继续比较重叠范围。 +4. 直到 $left\underline{\hspace{0.5em}}1 == len(slots1)$ 或者 $left\underline{\hspace{0.5em}}2 == len(slots2)$ 时跳出循环,返回空数组 $[]$。 ### 思路 1:代码 diff --git "a/Solutions/1245. \346\240\221\347\232\204\347\233\264\345\276\204.md" "b/Solutions/1245. \346\240\221\347\232\204\347\233\264\345\276\204.md" index ac9938c1..bdf8ded4 100644 --- "a/Solutions/1245. \346\240\221\347\232\204\347\233\264\345\276\204.md" +++ "b/Solutions/1245. \346\240\221\347\232\204\347\233\264\345\276\204.md" @@ -55,11 +55,11 @@ 即:**最长路径长度 = max(某子树中的最长路径长度 + 另一子树中的最长路径长度 + 1,某个子树中的最长路径长度)**。 -对此,我们可以使用深度优先搜索递归遍历 $u$ 的所有相邻节点 $v$,并在递归遍历的同时,维护一个全局最大路径和变量 $ans$,以及当前节点 $u$ 的最大路径长度变量 $u\underline{}len$。 +对此,我们可以使用深度优先搜索递归遍历 $u$ 的所有相邻节点 $v$,并在递归遍历的同时,维护一个全局最大路径和变量 $ans$,以及当前节点 $u$ 的最大路径长度变量 $u\underline{\hspace{0.5em}}len$。 -1. 先计算出从相邻节点 $v$ 出发的最长路径长度 $v\underline{}len$。 -2. 更新维护全局最长路径长度为 $self.ans = max(self.ans, \quad u\underline{}len + v\underline{}len + 1)$。 -3. 更新维护当前节点 $u$ 的最长路径长度为 $u\underline{}len = max(u\underline{}len, \quad v\underline{}len + 1)$。 +1. 先计算出从相邻节点 $v$ 出发的最长路径长度 $v\underline{\hspace{0.5em}}len$。 +2. 更新维护全局最长路径长度为 $self.ans = max(self.ans, \quad u\underline{\hspace{0.5em}}len + v\underline{\hspace{0.5em}}len + 1)$。 +3. 更新维护当前节点 $u$ 的最长路径长度为 $u\underline{\hspace{0.5em}}len = max(u\underline{\hspace{0.5em}}len, \quad v\underline{\hspace{0.5em}}len + 1)$。 > 注意:在遍历邻接节点的过程中,为了避免造成重复遍历,我们在使用深度优先搜索时,应过滤掉父节点。 diff --git "a/Solutions/1261. \345\234\250\345\217\227\346\261\241\346\237\223\347\232\204\344\272\214\345\217\211\346\240\221\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240.md" "b/Solutions/1261. \345\234\250\345\217\227\346\261\241\346\237\223\347\232\204\344\272\214\345\217\211\346\240\221\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240.md" index fa6b37a9..646a109b 100644 --- "a/Solutions/1261. \345\234\250\345\217\227\346\261\241\346\237\223\347\232\204\344\272\214\345\217\211\346\240\221\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240.md" +++ "b/Solutions/1261. \345\234\250\345\217\227\346\261\241\346\237\223\347\232\204\344\272\214\345\217\211\346\240\221\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240.md" @@ -71,7 +71,7 @@ findElements.find(5); // return False 1. 从根节点开始进行还原。 2. 然后使用深度优先搜索的方式,依次递归还原左右两个孩子节点。 -3. 递归还原的同时,将还原之后的所有节点值,存入集合 $val\underline{}set$ 中。 +3. 递归还原的同时,将还原之后的所有节点值,存入集合 $val\underline{\hspace{0.5em}}set$ 中。 这样就可以在 $O(1)$ 的时间复杂度内判断目标值 $target$ 是否在还原后的二叉树中了。 diff --git "a/Solutions/1300. \350\275\254\345\217\230\346\225\260\347\273\204\345\220\216\346\234\200\346\216\245\350\277\221\347\233\256\346\240\207\345\200\274\347\232\204\346\225\260\347\273\204\345\222\214.md" "b/Solutions/1300. \350\275\254\345\217\230\346\225\260\347\273\204\345\220\216\346\234\200\346\216\245\350\277\221\347\233\256\346\240\207\345\200\274\347\232\204\346\225\260\347\273\204\345\222\214.md" index 97575119..097a42a2 100644 --- "a/Solutions/1300. \350\275\254\345\217\230\346\225\260\347\273\204\345\220\216\346\234\200\346\216\245\350\277\221\347\233\256\346\240\207\345\200\274\347\232\204\346\225\260\347\273\204\345\222\214.md" +++ "b/Solutions/1300. \350\275\254\345\217\230\346\225\260\347\273\204\345\220\216\346\234\200\346\216\245\350\277\221\347\233\256\346\240\207\345\200\274\347\232\204\346\225\260\347\273\204\345\222\214.md" @@ -54,9 +54,9 @@ 整个算法步骤如下: -- 先对数组排序,并计算数组的前缀和 $pre\underline{}sum$。 +- 先对数组排序,并计算数组的前缀和 $pre\underline{\hspace{0.5em}}sum$。 - 通过二分查找在 $[0, arr[-1]]$ 中查找使得转变后数组和刚好大于等于 $target$ 的值 $value$。 -- 计算 $value$ 对应的数组和 $sum\underline{}1$,以及 $value - 1$ 对应的数组和 $sum\underline{}2$。并分别计算与 $target$ 的差值 $diff\underline{}1$、$diff\underline{}2$。 +- 计算 $value$ 对应的数组和 $sum\underline{\hspace{0.5em}}1$,以及 $value - 1$ 对应的数组和 $sum\underline{\hspace{0.5em}}2$。并分别计算与 $target$ 的差值 $diff\underline{\hspace{0.5em}}1$、$diff\underline{\hspace{0.5em}}2$。 - 输出差值小的那个值。 ### 思路 1:代码 diff --git "a/Solutions/1324. \347\253\226\347\233\264\346\211\223\345\215\260\345\215\225\350\257\215.md" "b/Solutions/1324. \347\253\226\347\233\264\346\211\223\345\215\260\345\215\225\350\257\215.md" index 3688821d..6b5526f6 100644 --- "a/Solutions/1324. \347\253\226\347\233\264\346\211\223\345\215\260\345\215\225\350\257\215.md" +++ "b/Solutions/1324. \347\253\226\347\233\264\346\211\223\345\215\260\345\215\225\350\257\215.md" @@ -50,7 +50,7 @@ ### 思路 1:模拟 1. 将字符串 $s$ 按空格分割为单词数组 $words$。 -2. 计算出单词数组 $words$ 中单词的最大长度 $max\underline{}len$。 +2. 计算出单词数组 $words$ 中单词的最大长度 $max\underline{\hspace{0.5em}}len$。 3. 第一重循环遍历竖直单词的每个单词位置 $i$,第二重循环遍历当前第 $j$ 个单词。 1. 如果当前单词没有第 $i$ 个字符(当前单词的长度超过了单词位置 $i$),则将空格插入到竖直单词中。 2. 如果当前单词有第 $i$ 个字符,泽讲当前单词的第 $i$ 个字符插入到竖直单词中。 diff --git "a/Solutions/1347. \345\210\266\351\200\240\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\347\232\204\346\234\200\345\260\217\346\255\245\351\252\244\346\225\260.md" "b/Solutions/1347. \345\210\266\351\200\240\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\347\232\204\346\234\200\345\260\217\346\255\245\351\252\244\346\225\260.md" index 17a4612c..b9e51f71 100644 --- "a/Solutions/1347. \345\210\266\351\200\240\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\347\232\204\346\234\200\345\260\217\346\255\245\351\252\244\346\225\260.md" +++ "b/Solutions/1347. \345\210\266\351\200\240\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\347\232\204\346\234\200\345\260\217\346\255\245\351\252\244\346\225\260.md" @@ -46,9 +46,9 @@ 因为每一次转换都会减少一个字符,并增加另一个字符。 -1. 我们使用两个哈希表 $cnts\underline{}s$、$cnts\underline{}t$ 分别对 $t$ 和 $s$ 中的字符进行计数,并求出两者的交集。 +1. 我们使用两个哈希表 $cnts\underline{\hspace{0.5em}}s$、$cnts\underline{\hspace{0.5em}}t$ 分别对 $t$ 和 $s$ 中的字符进行计数,并求出两者的交集。 2. 遍历交集中的字符种类,以及对应的字符数量。 -3. 对于当前字符 $key$,如果当前字符串 $s$ 中的字符 $key$ 的数量小于字符串 $t$ 中字符 $key$ 的数量,即 $cnts\underline{}s[key] < cnts\underline{}t[key]$。则 $s$ 中需要补齐的字符数量就是需要的最小步数,将其累加到答案中。 +3. 对于当前字符 $key$,如果当前字符串 $s$ 中的字符 $key$ 的数量小于字符串 $t$ 中字符 $key$ 的数量,即 $cnts\underline{\hspace{0.5em}}s[key] < cnts\underline{\hspace{0.5em}}t[key]$。则 $s$ 中需要补齐的字符数量就是需要的最小步数,将其累加到答案中。 4. 遍历完返回答案。 ### 思路 1:代码 diff --git "a/Solutions/1349. \345\217\202\345\212\240\350\200\203\350\257\225\347\232\204\346\234\200\345\244\247\345\255\246\347\224\237\346\225\260.md" "b/Solutions/1349. \345\217\202\345\212\240\350\200\203\350\257\225\347\232\204\346\234\200\345\244\247\345\255\246\347\224\237\346\225\260.md" index e5c87169..bb474b8d 100644 --- "a/Solutions/1349. \345\217\202\345\212\240\350\200\203\350\257\225\347\232\204\346\234\200\345\244\247\345\255\246\347\224\237\346\225\260.md" +++ "b/Solutions/1349. \345\217\202\345\212\240\350\200\203\350\257\225\347\232\204\346\234\200\345\244\247\345\255\246\347\224\237\346\225\260.md" @@ -70,15 +70,15 @@ ###### 3. 状态转移方程 -因为学生可以看到左侧、右侧、左上方、右上方这四个方向上紧邻他的学生答卷,所以对于当前排的某个座位来说,其左侧、右侧、左上方、右上方都不应有人坐。我们可以根据当前排的座位选取状态 $cur\underline{}state$,并通过枚举的方式,找出符合要求的上一排座位选取状态 $pre\underline{}state$,并计算出当前排座位选择个数,即 $f(cur\underline{}state)$,则状态转移方程为: +因为学生可以看到左侧、右侧、左上方、右上方这四个方向上紧邻他的学生答卷,所以对于当前排的某个座位来说,其左侧、右侧、左上方、右上方都不应有人坐。我们可以根据当前排的座位选取状态 $cur\underline{\hspace{0.5em}}state$,并通过枚举的方式,找出符合要求的上一排座位选取状态 $pre\underline{\hspace{0.5em}}state$,并计算出当前排座位选择个数,即 $f(cur\underline{\hspace{0.5em}}state)$,则状态转移方程为: - $dp[i][state] = \max \lbrace dp[i - 1][pre\underline{}state]\rbrace + f(state) $ + $dp[i][state] = \max \lbrace dp[i - 1][pre\underline{\hspace{0.5em}}state]\rbrace + f(state) $ -因为所给座位中还有坏座位(不可用)的情况,我们可以使用一个 $8$ 位的二进制数 $bad\underline{}seat$ 来表示当前排的坏座位情况,如果 $cur\underline{}state \text{ \& } bad\underline{}seat == 1$,则说明当前状态下,选择了坏椅子,则可直接跳过这种状态。 +因为所给座位中还有坏座位(不可用)的情况,我们可以使用一个 $8$ 位的二进制数 $bad\underline{\hspace{0.5em}}seat$ 来表示当前排的坏座位情况,如果 $cur\underline{\hspace{0.5em}}state \text{ \& } bad\underline{\hspace{0.5em}}seat == 1$,则说明当前状态下,选择了坏椅子,则可直接跳过这种状态。 -我们还可以通过 $cur\underline{}state \text{ \& } (cur\underline{}state \text{ <}\text{< } 1)$ 和 $cur\underline{}state \& (cur\underline{}state \text{ >}\text{> } 1)$ 来判断当前排选择状态下,左右相邻座位上是否有人,如果有人,则可直接跳过这种状态。 +我们还可以通过 $cur\underline{\hspace{0.5em}}state \text{ \& } (cur\underline{\hspace{0.5em}}state \text{ <}\text{< } 1)$ 和 $cur\underline{\hspace{0.5em}}state \& (cur\underline{\hspace{0.5em}}state \text{ >}\text{> } 1)$ 来判断当前排选择状态下,左右相邻座位上是否有人,如果有人,则可直接跳过这种状态。 -同理,我们还可以通过 $cur\underline{}state \text{ \& } (pre\underline{}state \text{ <}\text{< } 1)$ 和 $cur\underline{}state \text{ \& } (pre\underline{}state \text{ >}\text{> } 1)$ 来判断当前排选择状态下,上一行左上、右上相邻座位上是否有人,如果有人,则可直接跳过这种状态。 +同理,我们还可以通过 $cur\underline{\hspace{0.5em}}state \text{ \& } (pre\underline{\hspace{0.5em}}state \text{ <}\text{< } 1)$ 和 $cur\underline{\hspace{0.5em}}state \text{ \& } (pre\underline{\hspace{0.5em}}state \text{ >}\text{> } 1)$ 来判断当前排选择状态下,上一行左上、右上相邻座位上是否有人,如果有人,则可直接跳过这种状态。 ###### 4. 初始条件 diff --git "a/Solutions/1423. \345\217\257\350\216\267\345\276\227\347\232\204\346\234\200\345\244\247\347\202\271\346\225\260.md" "b/Solutions/1423. \345\217\257\350\216\267\345\276\227\347\232\204\346\234\200\345\244\247\347\202\271\346\225\260.md" index 84c14cdd..4eb5510b 100644 --- "a/Solutions/1423. \345\217\257\350\216\267\345\276\227\347\232\204\346\234\200\345\244\247\347\202\271\346\225\260.md" +++ "b/Solutions/1423. \345\217\257\350\216\267\345\276\227\347\232\204\346\234\200\345\244\247\347\202\271\346\225\260.md" @@ -47,17 +47,17 @@ 可以用固定长度的滑动窗口来做。 -由于只能从开头或末尾位置拿 $k$ 张牌,则最后剩下的肯定是连续的 $len(cardPoints) - k$ 张牌。要求求出 $k$ 张牌可以获得的最大收益,我们可以反向先求出连续 $len(cardPoints) - k$ 张牌的最小点数。则答案为 $sum(cardPoints) - min\underline{}sum$。维护一个固定长度为 $len(cardPoints) - k$ 的滑动窗口,求最小和。具体做法如下: +由于只能从开头或末尾位置拿 $k$ 张牌,则最后剩下的肯定是连续的 $len(cardPoints) - k$ 张牌。要求求出 $k$ 张牌可以获得的最大收益,我们可以反向先求出连续 $len(cardPoints) - k$ 张牌的最小点数。则答案为 $sum(cardPoints) - min\underline{\hspace{0.5em}}sum$。维护一个固定长度为 $len(cardPoints) - k$ 的滑动窗口,求最小和。具体做法如下: -1. $window\underline{}sum$ 用来维护窗口内的元素和,初始值为 $0$。$min\underline{}sum$ 用来维护滑动窗口元素的最小和。初始值为 $sum(cardPoints)$。滑动窗口的长度为 $window\underline{}size$,值为 $len(cardPoints) - k$。 +1. $window\underline{\hspace{0.5em}}sum$ 用来维护窗口内的元素和,初始值为 $0$。$min\underline{\hspace{0.5em}}sum$ 用来维护滑动窗口元素的最小和。初始值为 $sum(cardPoints)$。滑动窗口的长度为 $window\underline{\hspace{0.5em}}size$,值为 $len(cardPoints) - k$。 2. 使用双指针 $left$、$right$。$left$ 、$right$ 都指向序列的第一个元素,即:`left = 0`,`right = 0`。 -3. 向右移动 $right$,先将 $window\underline{}size$ 个元素填入窗口中。 -4. 当窗口元素个数为 $window\underline{}size$ 时,即:$right - left + 1 \ge window\underline{}size$ 时,计算窗口内的元素和,并维护子数组最小和 $min\underline{}sum$。 +3. 向右移动 $right$,先将 $window\underline{\hspace{0.5em}}size$ 个元素填入窗口中。 +4. 当窗口元素个数为 $window\underline{\hspace{0.5em}}size$ 时,即:$right - left + 1 \ge window\underline{\hspace{0.5em}}size$ 时,计算窗口内的元素和,并维护子数组最小和 $min\underline{\hspace{0.5em}}sum$。 5. 然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $k$。 6. 重复 4 ~ 5 步,直到 $right$ 到达数组末尾。 -7. 最后输出 $sum(cardPoints) - min\underline{}sum$ 即为答案。 +7. 最后输出 $sum(cardPoints) - min\underline{\hspace{0.5em}}sum$ 即为答案。 -注意:如果 $window\underline{}size$ 为 $0$ 时需要特殊判断,此时答案为数组和 $sum(cardPoints)$。 +注意:如果 $window\underline{\hspace{0.5em}}size$ 为 $0$ 时需要特殊判断,此时答案为数组和 $sum(cardPoints)$。 ### 思路 1:代码 diff --git "a/Solutions/1456. \345\256\232\351\225\277\345\255\220\344\270\262\344\270\255\345\205\203\351\237\263\347\232\204\346\234\200\345\244\247\346\225\260\347\233\256.md" "b/Solutions/1456. \345\256\232\351\225\277\345\255\220\344\270\262\344\270\255\345\205\203\351\237\263\347\232\204\346\234\200\345\244\247\346\225\260\347\233\256.md" index ec62fbf1..d6799643 100644 --- "a/Solutions/1456. \345\256\232\351\225\277\345\255\220\344\270\262\344\270\255\345\205\203\351\237\263\347\232\204\346\234\200\345\244\247\346\225\260\347\233\256.md" +++ "b/Solutions/1456. \345\256\232\351\225\277\345\255\220\344\270\262\344\270\255\345\205\203\351\237\263\347\232\204\346\234\200\345\244\247\346\225\260\347\233\256.md" @@ -44,9 +44,9 @@ 固定长度的滑动窗口题目。维护一个长度为 $k$ 的窗口,并统计滑动窗口中最大元音字母数。具体做法如下: -1. $ans$ 用来维护长度为 $k$ 的单个字符串中最大元音字母数。$window\underline{}count$ 用来维护窗口中元音字母数。集合 $vowel\underline{}set$ 用来存储元音字母。 +1. $ans$ 用来维护长度为 $k$ 的单个字符串中最大元音字母数。$window\underline{\hspace{0.5em}}count$ 用来维护窗口中元音字母数。集合 $vowel\underline{\hspace{0.5em}}set$ 用来存储元音字母。 2. $left$ 、$right$ 都指向字符串 $s$ 的第一个元素,即:$left = 0$,$right = 0$。 -3. 判断 $s[right]$ 是否在元音字母集合中,如果在则用 $window\underline{}count$ 进行计数。 +3. 判断 $s[right]$ 是否在元音字母集合中,如果在则用 $window\underline{\hspace{0.5em}}count$ 进行计数。 4. 当窗口元素个数为 $k$ 时,即:$right - left + 1 \ge k$ 时,更新 $ans$。然后判断 $s[left]$ 是否为元音字母,如果是则 `window_count -= 1`,并向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $k$。 5. 重复 $3 \sim 4$ 步,直到 $right$ 到达数组末尾。 6. 最后输出 $ans$。 diff --git "a/Solutions/1493. \345\210\240\346\216\211\344\270\200\344\270\252\345\205\203\347\264\240\344\273\245\345\220\216\345\205\250\344\270\272 1 \347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204.md" "b/Solutions/1493. \345\210\240\346\216\211\344\270\200\344\270\252\345\205\203\347\264\240\344\273\245\345\220\216\345\205\250\344\270\272 1 \347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204.md" index ce16204f..5e9280ca 100644 --- "a/Solutions/1493. \345\210\240\346\216\211\344\270\200\344\270\252\345\205\203\347\264\240\344\273\245\345\220\216\345\205\250\344\270\272 1 \347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204.md" +++ "b/Solutions/1493. \345\210\240\346\216\211\344\270\200\344\270\252\345\205\203\347\264\240\344\273\245\345\220\216\345\205\250\344\270\272 1 \347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204.md" @@ -42,13 +42,13 @@ 维护一个元素值为 $0$ 的元素数量少于 $1$ 个的滑动窗口。则答案为滑动窗口长度减去窗口内 $0$ 的个数求最大值。具体做法如下: -设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口 $0$ 的个数小于 $1$ 个。使用 $window\underline{}count$ 记录窗口中 $0$ 的个数,使用 $ans$ 记录删除一个元素后,最长的只包含 $1$ 的非空子数组长度。 +设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口 $0$ 的个数小于 $1$ 个。使用 $window\underline{\hspace{0.5em}}count$ 记录窗口中 $0$ 的个数,使用 $ans$ 记录删除一个元素后,最长的只包含 $1$ 的非空子数组长度。 - 一开始,$left$、$right$ 都指向 $0$。 - 如果最右侧元素等于 $0$,则 `window_count += 1` 。 -- 如果 $window\underline{}count > 1$ ,则不断右移 $left$,缩小滑动窗口长度。并更新当前窗口中 $0$ 的个数,直到 $window\underline{}count \le 1$。 +- 如果 $window\underline{\hspace{0.5em}}count > 1$ ,则不断右移 $left$,缩小滑动窗口长度。并更新当前窗口中 $0$ 的个数,直到 $window\underline{\hspace{0.5em}}count \le 1$。 - 更新答案值,然后向右移动 $right$,直到 $right \ge len(nums)$ 结束。 - 输出答案 $ans$。 diff --git "a/Solutions/1534. \347\273\237\350\256\241\345\245\275\344\270\211\345\205\203\347\273\204.md" "b/Solutions/1534. \347\273\237\350\256\241\345\245\275\344\270\211\345\205\203\347\273\204.md" index 2408dba8..916079a4 100644 --- "a/Solutions/1534. \347\273\237\350\256\241\345\245\275\344\270\211\345\205\203\347\273\204.md" +++ "b/Solutions/1534. \347\273\237\350\256\241\345\245\275\344\270\211\345\205\203\347\273\204.md" @@ -94,11 +94,11 @@ class Solution: 现在问题就转变了如何快速获取在值域区间 $[left, right]$ 中,有多少个 $arr[i]$。 -我们可以利用前缀和数组,先计算出 $[0, 1000]$ 范围中,满足 $arr[i] < num$ 的元素个数,即为 $prefix\underline{}cnts[num]$。 +我们可以利用前缀和数组,先计算出 $[0, 1000]$ 范围中,满足 $arr[i] < num$ 的元素个数,即为 $prefix\underline{\hspace{0.5em}}cnts[num]$。 -然后对于区间 $[left, right]$,通过 $prefix\underline{}cnts[right] - prefix\underline{}cnts[left - 1]$ 即可快速求解出区间 $[left, right]$ 内 $arr[i]$ 的个数。 +然后对于区间 $[left, right]$,通过 $prefix\underline{\hspace{0.5em}}cnts[right] - prefix\underline{\hspace{0.5em}}cnts[left - 1]$ 即可快速求解出区间 $[left, right]$ 内 $arr[i]$ 的个数。 -因为 $i < j < k$,所以我们可以在每次 $j$ 向右移动一位的时候,更新 $arr[j]$ 对应的前缀和数组,保证枚举到 $j$ 时,$prefix\underline{}cnts$ 存储对应元素值的个数足够正确。 +因为 $i < j < k$,所以我们可以在每次 $j$ 向右移动一位的时候,更新 $arr[j]$ 对应的前缀和数组,保证枚举到 $j$ 时,$prefix\underline{\hspace{0.5em}}cnts$ 存储对应元素值的个数足够正确。 ### 思路 2:代码 diff --git "a/Solutions/1582. \344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\347\211\271\346\256\212\344\275\215\347\275\256.md" "b/Solutions/1582. \344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\347\211\271\346\256\212\344\275\215\347\275\256.md" index e883f1fa..b995292a 100644 --- "a/Solutions/1582. \344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\347\211\271\346\256\212\344\275\215\347\275\256.md" +++ "b/Solutions/1582. \344\272\214\350\277\233\345\210\266\347\237\251\351\230\265\344\270\255\347\232\204\347\211\271\346\256\212\344\275\215\347\275\256.md" @@ -48,9 +48,9 @@ ### 思路 1:模拟 1. 按照行、列遍历二位数组 $mat$。 -2. 使用数组 $row\underline{}cnts$、$col\underline{}cnts$ 分别记录每行和每列所含 $1$ 的个数。 +2. 使用数组 $row\underline{\hspace{0.5em}}cnts$、$col\underline{\hspace{0.5em}}cnts$ 分别记录每行和每列所含 $1$ 的个数。 3. 再次按照行、列遍历二维数组 $mat$。 -4. 统计满足 $mat[row][col] == 1$ 并且 $row\underline{}cnts[row] == col\underline{}cnts[col] == 1$ 的位置个数。 +4. 统计满足 $mat[row][col] == 1$ 并且 $row\underline{\hspace{0.5em}}cnts[row] == col\underline{\hspace{0.5em}}cnts[col] == 1$ 的位置个数。 5. 返回答案。 ### 思路 1:代码 diff --git "a/Solutions/1593. \346\213\206\345\210\206\345\255\227\347\254\246\344\270\262\344\275\277\345\224\257\344\270\200\345\255\220\345\255\227\347\254\246\344\270\262\347\232\204\346\225\260\347\233\256\346\234\200\345\244\247.md" "b/Solutions/1593. \346\213\206\345\210\206\345\255\227\347\254\246\344\270\262\344\275\277\345\224\257\344\270\200\345\255\220\345\255\227\347\254\246\344\270\262\347\232\204\346\225\260\347\233\256\346\234\200\345\244\247.md" index 969c397c..e34c4b63 100644 --- "a/Solutions/1593. \346\213\206\345\210\206\345\255\227\347\254\246\344\270\262\344\275\277\345\224\257\344\270\200\345\255\220\345\255\227\347\254\246\344\270\262\347\232\204\346\225\260\347\233\256\346\234\200\345\244\247.md" +++ "b/Solutions/1593. \346\213\206\345\210\206\345\255\227\347\254\246\344\270\262\344\275\277\345\224\257\344\270\200\345\255\220\345\255\227\347\254\246\344\270\262\347\232\204\346\225\260\347\233\256\346\234\200\345\244\247.md" @@ -41,12 +41,12 @@ ### 思路 1:回溯算法 -维护一个全局变量 $ans$ 用于记录拆分后唯一子字符串的最大数目。并使用集合 $s\underline{}set$ 记录不重复的子串。 +维护一个全局变量 $ans$ 用于记录拆分后唯一子字符串的最大数目。并使用集合 $s\underline{\hspace{0.5em}}set$ 记录不重复的子串。 - 从下标为 $0$ 开头的子串回溯。 - 对于下标为 $index$ 开头的子串,我们可以在 $index + 1$ 开始到 $len(s) - 1$ 的位置上,分别进行子串拆分,将子串拆分为 $s[index: i + 1]$。 -- 如果当前子串不在 $s\underline{}set$ 中,则将其存入 $s\underline{}set$ 中,然后记录当前拆分子串个数,并从 $i + 1$ 的位置进行下一层递归拆分。然后在拆分完,对子串进行回退操作。 +- 如果当前子串不在 $s\underline{\hspace{0.5em}}set$ 中,则将其存入 $s\underline{\hspace{0.5em}}set$ 中,然后记录当前拆分子串个数,并从 $i + 1$ 的位置进行下一层递归拆分。然后在拆分完,对子串进行回退操作。 - 如果拆到字符串 $s$ 的末尾,则记录并更新 $ans$。 - 在开始位置还可以进行以下剪枝:如果剩余字符个数 + 当前子串个数 <= 当前拆分后子字符串的最大数目,则直接返回。 diff --git "a/Solutions/1647. \345\255\227\347\254\246\351\242\221\346\254\241\345\224\257\344\270\200\347\232\204\346\234\200\345\260\217\345\210\240\351\231\244\346\254\241\346\225\260.md" "b/Solutions/1647. \345\255\227\347\254\246\351\242\221\346\254\241\345\224\257\344\270\200\347\232\204\346\234\200\345\260\217\345\210\240\351\231\244\346\254\241\346\225\260.md" index b56470ed..a83e74c3 100644 --- "a/Solutions/1647. \345\255\227\347\254\246\351\242\221\346\254\241\345\224\257\344\270\200\347\232\204\346\234\200\345\260\217\345\210\240\351\231\244\346\254\241\346\225\260.md" +++ "b/Solutions/1647. \345\255\227\347\254\246\351\242\221\346\254\241\345\224\257\344\270\200\347\232\204\346\234\200\345\260\217\345\210\240\351\231\244\346\254\241\346\225\260.md" @@ -44,10 +44,10 @@ ### 思路 1:贪心算法 + 哈希表 1. 使用哈希表 $cnts$ 统计每字符串中每个字符出现次数。 -2. 然后使用集合 $s\underline{}set$ 保存不同的出现次数。 +2. 然后使用集合 $s\underline{\hspace{0.5em}}set$ 保存不同的出现次数。 3. 遍历哈希表中所偶出现次数: - 1. 如果当前出现次数不在集合 $s\underline{}set$ 中,则将该次数添加到集合 $s\underline{}set$ 中。 - 2. 如果当前出现次数在集合 $s\underline{}set$ 中,则不断减少该次数,直到该次数不在集合 $s\underline{}set$ 中停止,将次数添加到集合 $s\underline{}set$ 中,同时将减少次数累加到答案 $ans$ 中。 + 1. 如果当前出现次数不在集合 $s\underline{\hspace{0.5em}}set$ 中,则将该次数添加到集合 $s\underline{\hspace{0.5em}}set$ 中。 + 2. 如果当前出现次数在集合 $s\underline{\hspace{0.5em}}set$ 中,则不断减少该次数,直到该次数不在集合 $s\underline{\hspace{0.5em}}set$ 中停止,将次数添加到集合 $s\underline{\hspace{0.5em}}set$ 中,同时将减少次数累加到答案 $ans$ 中。 4. 遍历完哈希表后返回答案 $ans$。 ### 思路 1:代码 diff --git "a/Solutions/1658. \345\260\206 x \345\207\217\345\210\260 0 \347\232\204\346\234\200\345\260\217\346\223\215\344\275\234\346\225\260.md" "b/Solutions/1658. \345\260\206 x \345\207\217\345\210\260 0 \347\232\204\346\234\200\345\260\217\346\223\215\344\275\234\346\225\260.md" index 4301bd88..852daf04 100644 --- "a/Solutions/1658. \345\260\206 x \345\207\217\345\210\260 0 \347\232\204\346\234\200\345\260\217\346\223\215\344\275\234\346\225\260.md" +++ "b/Solutions/1658. \345\260\206 x \345\207\217\345\210\260 0 \347\232\204\346\234\200\345\260\217\346\223\215\344\275\234\346\225\260.md" @@ -43,14 +43,14 @@ 将 $x$ 减到 $0$ 的最小操作数可以转换为求和等于 $sum(nums) - x$ 的最长连续子数组长度。我们可以维护一个区间和为 $sum(nums) - x$ 的滑动窗口,求出最长的窗口长度。具体做法如下: -令 `target = sum(nums) - x`,使用 $max\underline{}len$ 维护和等于 $target$ 的最长连续子数组长度。然后用滑动窗口 $window\underline{}sum$ 来记录连续子数组的和,设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口中的和刚好等于 $target$。 +令 `target = sum(nums) - x`,使用 $max\underline{\hspace{0.5em}}len$ 维护和等于 $target$ 的最长连续子数组长度。然后用滑动窗口 $window\underline{\hspace{0.5em}}sum$ 来记录连续子数组的和,设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口中的和刚好等于 $target$。 - 一开始,$left$、$right$ 都指向 $0$。 -- 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{}sum$ 中。 -- 如果 $window\underline{}sum > target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{}sum \le target$。 -- 如果 $window\underline{}sum == target$,则更新最长连续子数组长度。 +- 向右移动 $right$,将最右侧元素加入当前窗口和 $window\underline{\hspace{0.5em}}sum$ 中。 +- 如果 $window\underline{\hspace{0.5em}}sum > target$,则不断右移 $left$,缩小滑动窗口长度,并更新窗口和的最小值,直到 $window\underline{\hspace{0.5em}}sum \le target$。 +- 如果 $window\underline{\hspace{0.5em}}sum == target$,则更新最长连续子数组长度。 - 然后继续右移 $right$,直到 $right \ge len(nums)$ 结束。 -- 输出 $len(nums) - max\underline{}len$ 作为答案。 +- 输出 $len(nums) - max\underline{\hspace{0.5em}}len$ 作为答案。 - 注意判断题目中的特殊情况。 ### 思路 1:代码 diff --git "a/Solutions/1672. \346\234\200\345\257\214\346\234\211\345\256\242\346\210\267\347\232\204\350\265\204\344\272\247\346\200\273\351\207\217.md" "b/Solutions/1672. \346\234\200\345\257\214\346\234\211\345\256\242\346\210\267\347\232\204\350\265\204\344\272\247\346\200\273\351\207\217.md" index 9e0f6c7b..8f27d192 100644 --- "a/Solutions/1672. \346\234\200\345\257\214\346\234\211\345\256\242\346\210\267\347\232\204\350\265\204\344\272\247\346\200\273\351\207\217.md" +++ "b/Solutions/1672. \346\234\200\345\257\214\346\234\211\345\256\242\346\210\267\347\232\204\350\265\204\344\272\247\346\200\273\351\207\217.md" @@ -51,10 +51,10 @@ ### 思路 1:直接模拟 -1. 使用变量 $max\underline{}ans$ 存储最富有客户所拥有的资产总量。 +1. 使用变量 $max\underline{\hspace{0.5em}}ans$ 存储最富有客户所拥有的资产总量。 2. 遍历所有客户,对于当前客户 $accounts[i]$,统计其拥有的资产总量。 -3. 将当前客户的资产总量与 $max\underline{}ans$ 进行比较,如果大于 $max\underline{}ans$,则更新 $max\underline{}ans$ 的值。 -4. 遍历完所有客户,最终返回 $max\underline{}ans$ 作为结果。 +3. 将当前客户的资产总量与 $max\underline{\hspace{0.5em}}ans$ 进行比较,如果大于 $max\underline{\hspace{0.5em}}ans$,则更新 $max\underline{\hspace{0.5em}}ans$ 的值。 +4. 遍历完所有客户,最终返回 $max\underline{\hspace{0.5em}}ans$ 作为结果。 ### 思路 1:代码 diff --git "a/Solutions/1695. \345\210\240\351\231\244\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\276\227\345\210\206.md" "b/Solutions/1695. \345\210\240\351\231\244\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\276\227\345\210\206.md" index e9119f47..90ef3bf5 100644 --- "a/Solutions/1695. \345\210\240\351\231\244\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\276\227\345\210\206.md" +++ "b/Solutions/1695. \345\210\240\351\231\244\345\255\220\346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\345\276\227\345\210\206.md" @@ -43,7 +43,7 @@ 题目要求的是含有不同元素的连续子数组最大和,我们可以用滑动窗口来做,维护一个不包含重复元素的滑动窗口,计算最大的窗口和。具体方法如下: -- 用滑动窗口 $window$ 来记录不重复的元素个数,$window$ 为哈希表类型。用 $window\underline{}sum$ 来记录窗口内子数组元素和,$ans$ 用来维护最大子数组和。设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口中没有重复元素。 +- 用滑动窗口 $window$ 来记录不重复的元素个数,$window$ 为哈希表类型。用 $window\underline{\hspace{0.5em}}sum$ 来记录窗口内子数组元素和,$ans$ 用来维护最大子数组和。设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口中没有重复元素。 - 一开始,$left$、$right$ 都指向 $0$。 - 将最右侧数组元素 $nums[right]$ 加入当前窗口 $window$ 中,记录该元素个数。 diff --git "a/Solutions/1859. \345\260\206\345\217\245\345\255\220\346\216\222\345\272\217.md" "b/Solutions/1859. \345\260\206\345\217\245\345\255\220\346\216\222\345\272\217.md" index 24ff0f22..cd09cfb6 100644 --- "a/Solutions/1859. \345\260\206\345\217\245\345\255\220\346\216\222\345\272\217.md" +++ "b/Solutions/1859. \345\260\206\345\217\245\345\255\220\346\216\222\345\272\217.md" @@ -46,8 +46,8 @@ ### 思路 1:模拟 -1. 将句子 $s$ 按照空格分隔成数组 $s\underline{}list$。 -2. 遍历数组 $s\underline{}list$ 中的单词: +1. 将句子 $s$ 按照空格分隔成数组 $s\underline{\hspace{0.5em}}list$。 +2. 遍历数组 $s\underline{\hspace{0.5em}}list$ 中的单词: 1. 从单词中分割出对应单词索引 $idx$ 和对应单词 $word$。 2. 将单词 $word$ 存入答案数组 $res$ 对应位置 $idx - 1$ 上,即:$res[int(idx) - 1] = word$。 3. 将答案数组用空格拼接成句子字符串,并返回。 diff --git "a/Solutions/1879. \344\270\244\344\270\252\346\225\260\347\273\204\346\234\200\345\260\217\347\232\204\345\274\202\346\210\226\345\200\274\344\271\213\345\222\214.md" "b/Solutions/1879. \344\270\244\344\270\252\346\225\260\347\273\204\346\234\200\345\260\217\347\232\204\345\274\202\346\210\226\345\200\274\344\271\213\345\222\214.md" index 5f9f8c88..54650974 100644 --- "a/Solutions/1879. \344\270\244\344\270\252\346\225\260\347\273\204\346\234\200\345\260\217\347\232\204\345\274\202\346\210\226\345\200\274\344\271\213\345\222\214.md" +++ "b/Solutions/1879. \344\270\244\344\270\252\346\225\260\347\273\204\346\234\200\345\260\217\347\232\204\345\274\202\346\210\226\345\200\274\344\271\213\345\222\214.md" @@ -77,7 +77,7 @@ 举个例子 $nums2 = \lbrace 1, 2, 3, 4 \rbrace$,$state = (1001)_2$,表示选择了第 $1$ 个元素和第 $4$ 个元素,也就是 $1$、$4$。那么 $state$ 只能从 $(1000)_2$ 和 $(0001)_2$ 这两个状态转移而来,我们只需要枚举这两种状态,并求出转移过来的异或值之和最小值。 -即状态转移方程为:$dp[state] = min(dp[state], \quad dp[state \oplus (1 \text{ <}\text{< } i)] + (nums1[i] \oplus nums2[one\underline{}cnt - 1]))$,其中 $state$ 第 $i$ 位一定为 $1$,$one\underline{}cnt$ 为 $state$ 中 $1$ 的个数。 +即状态转移方程为:$dp[state] = min(dp[state], \quad dp[state \oplus (1 \text{ <}\text{< } i)] + (nums1[i] \oplus nums2[one\underline{\hspace{0.5em}}cnt - 1]))$,其中 $state$ 第 $i$ 位一定为 $1$,$one\underline{\hspace{0.5em}}cnt$ 为 $state$ 中 $1$ 的个数。 ###### 4. 初始条件 diff --git "a/Solutions/1947. \346\234\200\345\244\247\345\205\274\345\256\271\346\200\247\350\257\204\345\210\206\345\222\214.md" "b/Solutions/1947. \346\234\200\345\244\247\345\205\274\345\256\271\346\200\247\350\257\204\345\210\206\345\222\214.md" index 6b669c99..18955b88 100644 --- "a/Solutions/1947. \346\234\200\345\244\247\345\205\274\345\256\271\346\200\247\350\257\204\345\210\206\345\222\214.md" +++ "b/Solutions/1947. \346\234\200\345\244\247\345\205\274\345\256\271\346\200\247\350\257\204\345\210\206\345\222\214.md" @@ -69,11 +69,11 @@ 对于当前状态 $state$,肯定是从比 $state$ 少选一个老师被分配的状态中递推而来。我们可以枚举少选一个元素的状态,找到可以得到的最大兼容性评分和,赋值给 $dp[state]$。 -即状态转移方程为:$dp[state] = max(dp[state], \quad dp[state \oplus (1 \text{ <}\text{< } i)] + score[i][one\underline{}cnt - 1])$,其中: +即状态转移方程为:$dp[state] = max(dp[state], \quad dp[state \oplus (1 \text{ <}\text{< } i)] + score[i][one\underline{\hspace{0.5em}}cnt - 1])$,其中: 1. $state$ 第 $i$ 位一定为 $1$。 2. $state \oplus (1 \text{ <}\text{< } i)$ 为比 $state$ 少选一个元素的状态。 -3. $scores[i][one\underline{}cnt - 1]$ 为第 $i$ 名老师分配到第 $one\underline{}cnt - 1$ 名学生的兼容性评分。 +3. $scores[i][one\underline{\hspace{0.5em}}cnt - 1]$ 为第 $i$ 名老师分配到第 $one\underline{\hspace{0.5em}}cnt - 1$ 名学生的兼容性评分。 关于每位老师与每位同学之间的兼容性评分,我们可以事先通过一个 $m \times m \times n$ 的三重循环计算得出,并且存入到 $m \times m$ 大小的二维矩阵 $scores$ 中。 diff --git "a/Solutions/1991. \346\211\276\345\210\260\346\225\260\347\273\204\347\232\204\344\270\255\351\227\264\344\275\215\347\275\256.md" "b/Solutions/1991. \346\211\276\345\210\260\346\225\260\347\273\204\347\232\204\344\270\255\351\227\264\344\275\215\347\275\256.md" index 8d957b5c..e409e92d 100644 --- "a/Solutions/1991. \346\211\276\345\210\260\346\225\260\347\273\204\347\232\204\344\270\255\351\227\264\344\275\215\347\275\256.md" +++ "b/Solutions/1991. \346\211\276\345\210\260\346\225\260\347\273\204\347\232\204\344\270\255\351\227\264\344\275\215\347\275\256.md" @@ -45,10 +45,10 @@ ### 思路 1:前缀和 1. 先遍历一遍数组,求出数组中全部元素和为 $total$。 -2. 再遍历一遍数组,使用变量 $prefix\underline{}sum$ 为前 $i$ 个元素和。 -3. 当遍历到第 $i$ 个元素时,其数组左侧元素之和为 $prefix\underline{}sum$,右侧元素和为 $total - prefix\underline{}sum - nums[i]$。 - 1. 如果左右元素之和相等,即 $prefix\underline{}sum == total - prefix\underline{}sum - nums[i]$($2 \times prefix\underline{}sum + nums[i] == total$) 时,$i$ 为中间位置。此时返回 $i$。 - 2. 如果不满足,则继续累加当前元素到 $prefix\underline{}sum$ 中,继续向后遍历。 +2. 再遍历一遍数组,使用变量 $prefix\underline{\hspace{0.5em}}sum$ 为前 $i$ 个元素和。 +3. 当遍历到第 $i$ 个元素时,其数组左侧元素之和为 $prefix\underline{\hspace{0.5em}}sum$,右侧元素和为 $total - prefix\underline{\hspace{0.5em}}sum - nums[i]$。 + 1. 如果左右元素之和相等,即 $prefix\underline{\hspace{0.5em}}sum == total - prefix\underline{\hspace{0.5em}}sum - nums[i]$($2 \times prefix\underline{\hspace{0.5em}}sum + nums[i] == total$) 时,$i$ 为中间位置。此时返回 $i$。 + 2. 如果不满足,则继续累加当前元素到 $prefix\underline{\hspace{0.5em}}sum$ 中,继续向后遍历。 4. 如果找不到符合要求的中间位置,则返回 $-1$。 ### 思路 1:代码 diff --git "a/Solutions/1994. \345\245\275\345\255\220\351\233\206\347\232\204\346\225\260\347\233\256.md" "b/Solutions/1994. \345\245\275\345\255\220\351\233\206\347\232\204\346\225\260\347\233\256.md" index f9d5bb9b..fbca0c07 100644 --- "a/Solutions/1994. \345\245\275\345\255\220\351\233\206\347\232\204\346\225\260\347\233\256.md" +++ "b/Solutions/1994. \345\245\275\345\255\220\351\233\206\347\232\204\346\225\260\347\233\256.md" @@ -79,9 +79,9 @@ ###### 3. 状态转移方程 -对于 $nums$ 中的每个数 $num$,其对应出现次数为 $cnt$。我们可以通过试除法,将 $num$ 分解为不同的质因数,并使用「状态压缩」的方式,用一个二进制数 $cur\underline{}state$ 来表示当前数 $num$ 中使用了哪些质因数。然后枚举所有状态,找到与 $cur\underline{}state$ 不冲突的状态 $state$(也就是除了 $cur\underline{}state$ 中选择的质因数外,选择的其他质因数情况,比如 $cur\underline{}state$ 选择了 $2$ 和 $5$,则枚举不选择 $2$ 和 $5$ 的状态)。 +对于 $nums$ 中的每个数 $num$,其对应出现次数为 $cnt$。我们可以通过试除法,将 $num$ 分解为不同的质因数,并使用「状态压缩」的方式,用一个二进制数 $cur\underline{\hspace{0.5em}}state$ 来表示当前数 $num$ 中使用了哪些质因数。然后枚举所有状态,找到与 $cur\underline{\hspace{0.5em}}state$ 不冲突的状态 $state$(也就是除了 $cur\underline{\hspace{0.5em}}state$ 中选择的质因数外,选择的其他质因数情况,比如 $cur\underline{\hspace{0.5em}}state$ 选择了 $2$ 和 $5$,则枚举不选择 $2$ 和 $5$ 的状态)。 -此时,状态转移方程为:$dp[state | cur\underline{}state] = \sum (dp[state] \times cnt) \mod MOD , \quad state \text{ \& } cur\underline{}state == 0$ +此时,状态转移方程为:$dp[state | cur\underline{\hspace{0.5em}}state] = \sum (dp[state] \times cnt) \mod MOD , \quad state \text{ \& } cur\underline{\hspace{0.5em}}state == 0$ ###### 4. 初始条件 diff --git "a/Solutions/2172. \346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\344\270\216\345\222\214.md" "b/Solutions/2172. \346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\344\270\216\345\222\214.md" index 1e5eb2c9..3d1bd402 100644 --- "a/Solutions/2172. \346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\344\270\216\345\222\214.md" +++ "b/Solutions/2172. \346\225\260\347\273\204\347\232\204\346\234\200\345\244\247\344\270\216\345\222\214.md" @@ -71,12 +71,12 @@ 对于当前状态 $dp[state]$,肯定是从比 $state$ 少选一个元素的状态中递推而来。我们可以枚举少选一个元素的状态,找到可以获得的最大与和,赋值给 $dp[state]$。 -即状态转移方程为:$dp[state] = min(dp[state], dp[state \oplus (1 \text{ <}\text{< } i)] + (i // 2 + 1) \text{ \& } nums[one\underline{}cnt - 1])$,其中: +即状态转移方程为:$dp[state] = min(dp[state], dp[state \oplus (1 \text{ <}\text{< } i)] + (i // 2 + 1) \text{ \& } nums[one\underline{\hspace{0.5em}}cnt - 1])$,其中: 1. $state$ 第 $i$ 位一定为 $1$。 2. $state \oplus (1 \text{ <}\text{< } i)$ 为比 $state$ 少选一个元素的状态。 3. $i // 2 + 1$ 为篮子对应编号 -4. $nums[one\underline{}cnt - 1]$ 为当前正在考虑的数组元素。 +4. $nums[one\underline{\hspace{0.5em}}cnt - 1]$ 为当前正在考虑的数组元素。 ###### 4. 初始条件 @@ -86,7 +86,7 @@ 根据我们之前定义的状态,$dp[state]$ 表示为:将前 $count(state)$ 个整数放到篮子里,并且每个篮子中的整数放取情况为 $state$ 时,可以获得的最大与和。所以最终结果为 $max(dp)$。 -> 注意:当 $one\underline{}cnt > len(nums)$ 时,无法通过递推得到 $dp[state]$,需要跳过。 +> 注意:当 $one\underline{\hspace{0.5em}}cnt > len(nums)$ 时,无法通过递推得到 $dp[state]$,需要跳过。 ### 思路 1:代码 diff --git "a/Solutions/2246. \347\233\270\351\202\273\345\255\227\347\254\246\344\270\215\345\220\214\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204.md" "b/Solutions/2246. \347\233\270\351\202\273\345\255\227\347\254\246\344\270\215\345\220\214\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204.md" index 2624be4d..59192358 100644 --- "a/Solutions/2246. \347\233\270\351\202\273\345\255\227\347\254\246\344\270\215\345\220\214\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204.md" +++ "b/Solutions/2246. \347\233\270\351\202\273\345\255\227\347\254\246\344\270\215\345\220\214\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204.md" @@ -60,11 +60,11 @@ 即:**最长路径长度 = max(某子树中的最长路径长度 + 另一子树中的最长路径长度 + 1,某个子树中的最长路径长度)**。 -对此,我们可以使用深度优先搜索递归遍历 $u$ 的所有相邻节点 $v$,并在递归遍历的同时,维护一个全局最大路径和变量 $ans$,以及当前节点 $u$ 的最大路径长度变量 $u\underline{}len$。 +对此,我们可以使用深度优先搜索递归遍历 $u$ 的所有相邻节点 $v$,并在递归遍历的同时,维护一个全局最大路径和变量 $ans$,以及当前节点 $u$ 的最大路径长度变量 $u\underline{\hspace{0.5em}}len$。 -1. 先计算出从相邻节点 $v$ 出发的最长路径长度 $v\underline{}len$。 -2. 更新维护全局最长路径长度为 $self.ans = max(self.ans, \quad u\underline{}len + v\underline{}len + 1)$。 -3. 更新维护当前节点 $u$ 的最长路径长度为 $u\underline{}len = max(u\underline{}len, \quad v\underline{}len + 1)$。 +1. 先计算出从相邻节点 $v$ 出发的最长路径长度 $v\underline{\hspace{0.5em}}len$。 +2. 更新维护全局最长路径长度为 $self.ans = max(self.ans, \quad u\underline{\hspace{0.5em}}len + v\underline{\hspace{0.5em}}len + 1)$。 +3. 更新维护当前节点 $u$ 的最长路径长度为 $u\underline{\hspace{0.5em}}len = max(u\underline{\hspace{0.5em}}len, \quad v\underline{\hspace{0.5em}}len + 1)$。 因为题目限定了「相邻节点字符不同」,所以在更新全局最长路径长度和当前节点 $u$ 的最长路径长度时,我们需要判断一下节点 $u$ 与相邻节点 $v$ 的字符是否相同,只有在字符不同的条件下,才能够更新维护。 diff --git "a/Solutions/2538. \346\234\200\345\244\247\344\273\267\345\200\274\345\222\214\344\270\216\346\234\200\345\260\217\344\273\267\345\200\274\345\222\214\347\232\204\345\267\256\345\200\274.md" "b/Solutions/2538. \346\234\200\345\244\247\344\273\267\345\200\274\345\222\214\344\270\216\346\234\200\345\260\217\344\273\267\345\200\274\345\222\214\347\232\204\345\267\256\345\200\274.md" index 7ac58ab9..70cb637f 100644 --- "a/Solutions/2538. \346\234\200\345\244\247\344\273\267\345\200\274\345\222\214\344\270\216\346\234\200\345\260\217\344\273\267\345\200\274\345\222\214\347\232\204\345\267\256\345\200\274.md" +++ "b/Solutions/2538. \346\234\200\345\244\247\344\273\267\345\200\274\345\222\214\344\270\216\346\234\200\345\260\217\344\273\267\345\200\274\345\222\214\347\232\204\345\267\256\345\200\274.md" @@ -66,22 +66,22 @@ 对此我们可以使用深度优先搜索递归遍历二叉树,并在递归遍历的同时,维护一个最大开销变量 $ans$。 -然后定义函数 ` def dfs(self, u, father):` 计算以节点 $u$ 为根节点的子树中,带端点的最大路径和 $max\underline{}s1$,以及去掉端点的最大路径和 $max\underline{}s2$,其中 $father$ 表示节点 $u$ 的根节点,用于遍历邻接节点的过程中过滤父节点,避免重复遍历。 +然后定义函数 ` def dfs(self, u, father):` 计算以节点 $u$ 为根节点的子树中,带端点的最大路径和 $max\underline{\hspace{0.5em}}s1$,以及去掉端点的最大路径和 $max\underline{\hspace{0.5em}}s2$,其中 $father$ 表示节点 $u$ 的根节点,用于遍历邻接节点的过程中过滤父节点,避免重复遍历。 -初始化带端点的最大路径和 $max\underline{}s1$ 为 $price[u]$,表示当前只有一个节点,初始化去掉端点的最大路径和 $max\underline{}s2$ 为 $0$,表示当前没有节点。 +初始化带端点的最大路径和 $max\underline{\hspace{0.5em}}s1$ 为 $price[u]$,表示当前只有一个节点,初始化去掉端点的最大路径和 $max\underline{\hspace{0.5em}}s2$ 为 $0$,表示当前没有节点。 然后在遍历节点 $u$ 的相邻节点 $v$ 时,递归调用 $dfs(v, u)$,获取以节点 $v$ 为根节点的子树中,带端点的最大路径和 $s1$,以及去掉端点的最大路径和 $s2$。此时最大开销变量 $self.ans$ 有两种情况: -1. $u$ 的子树中带端点的最大路径和,加上 $v$ 的子树中不带端点的最大路径和,即:$max\underline{}s1 + s2$。 -2. $u$ 的子树中去掉端点的最大路径和,加上 $v$ 的子树中带端点的最大路径和,即:$max\underline{}s2 + s1$。 +1. $u$ 的子树中带端点的最大路径和,加上 $v$ 的子树中不带端点的最大路径和,即:$max\underline{\hspace{0.5em}}s1 + s2$。 +2. $u$ 的子树中去掉端点的最大路径和,加上 $v$ 的子树中带端点的最大路径和,即:$max\underline{\hspace{0.5em}}s2 + s1$。 -此时我们更新最大开销变量 $self.ans$,即:$self.ans = max(self.ans, \quad max\underline{}s1 + s2, \quad max\underline{}s2 + s1)$。 +此时我们更新最大开销变量 $self.ans$,即:$self.ans = max(self.ans, \quad max\underline{\hspace{0.5em}}s1 + s2, \quad max\underline{\hspace{0.5em}}s2 + s1)$。 -然后更新 $u$ 的子树中带端点的最大路径和 $max\underline{}s1$,即:$max\underline{}s1= max(max\underline{}s1, \quad s1 + price[u])$。 +然后更新 $u$ 的子树中带端点的最大路径和 $max\underline{\hspace{0.5em}}s1$,即:$max\underline{\hspace{0.5em}}s1= max(max\underline{\hspace{0.5em}}s1, \quad s1 + price[u])$。 -再更新 $u$ 的子树中去掉端点的最大路径和 $max\underline{}s2$,即:$max\underline{}s2 = max(max\underline{}s2, \quad s2 + price[u])$。 +再更新 $u$ 的子树中去掉端点的最大路径和 $max\underline{\hspace{0.5em}}s2$,即:$max\underline{\hspace{0.5em}}s2 = max(max\underline{\hspace{0.5em}}s2, \quad s2 + price[u])$。 -最后返回带端点 $u$ 的最大路径和 $max\underline{}s1$,以及去掉端点 $u$ 的最大路径和 $。 +最后返回带端点 $u$ 的最大路径和 $max\underline{\hspace{0.5em}}s1$,以及去掉端点 $u$ 的最大路径和 $。 最终,最大开销变量 $self.ans$ 即为答案。 diff --git "a/Solutions/2719. \347\273\237\350\256\241\346\225\264\346\225\260\346\225\260\347\233\256.md" "b/Solutions/2719. \347\273\237\350\256\241\346\225\264\346\225\260\346\225\260\347\233\256.md" index 4d6f8bef..30a70a8d 100644 --- "a/Solutions/2719. \347\273\237\350\256\241\346\225\264\346\225\260\346\225\260\347\233\256.md" +++ "b/Solutions/2719. \347\273\237\350\256\241\346\225\264\346\225\260\346\225\260\347\233\256.md" @@ -9,7 +9,7 @@ ## 题目大意 -**描述**:给定两个数字字符串 $num1$ 和 $num2$,以及两个整数 $max\underline{}sum$ 和 $min\underline{}sum$。 +**描述**:给定两个数字字符串 $num1$ 和 $num2$,以及两个整数 $max\underline{\hspace{0.5em}}sum$ 和 $min\underline{\hspace{0.5em}}sum$。 **要求**:返回好整数的数目。答案可能很大,请返回答案对 $10^9 + 7$ 取余后的结果。 @@ -17,11 +17,11 @@ - **好整数**:如果一个整数 $x$ 满足一下条件,我们称它是一个好整数: - $num1 \le x \le num2$。 - - $num\underline{}sum \le digit\underline{}sum(x) \le max\underline{}sum$。 + - $num\underline{\hspace{0.5em}}sum \le digit\underline{\hspace{0.5em}}sum(x) \le max\underline{\hspace{0.5em}}sum$。 -- $digit\underline{}sum(x)$ 表示 $x$ 各位数字之和。 +- $digit\underline{\hspace{0.5em}}sum(x)$ 表示 $x$ 各位数字之和。 - $1 \le num1 \le num2 \le 10^{22}$。 -- $1 \le min\underline{}sum \le max\underline{}sum \le 400$。 +- $1 \le min\underline{\hspace{0.5em}}sum \le max\underline{\hspace{0.5em}}sum \le 400$。 **示例**: @@ -52,9 +52,9 @@ 2. 初始数位和为 $0$。 3. 开始时当前数位最大值受到最高位数位的约束。 4. 开始时当前数位最小值受到最高位数位的约束。 -2. 如果 $total > max\underline{}sum$,说明当前方案不符合要求,则返回方案数 $0$。 +2. 如果 $total > max\underline{\hspace{0.5em}}sum$,说明当前方案不符合要求,则返回方案数 $0$。 3. 如果遇到 $pos == len(s)$,表示到达数位末尾,此时: - 1. 如果 $min\underline{}sum \le total \le max\underline{}sum$,说明当前方案符合要求,则返回方案数 $1$。 + 1. 如果 $min\underline{\hspace{0.5em}}sum \le total \le max\underline{\hspace{0.5em}}sum$,说明当前方案符合要求,则返回方案数 $1$。 2. 如果不满足,则当前方案不符合要求,则返回方案数 $0$。 4. 如果 $pos \ne len(s)$,则定义方案数 $ans$,令其等于 $0$,即:`ans = 0`。 5. 根据 $isMaxLimit$ 和 $isMinLimit$ 来决定填当前位数位所能选择的最小数字($minX$)和所能选择的最大数字($maxX$)。 @@ -106,5 +106,5 @@ class Solution: ### 思路 1:复杂度分析 - **时间复杂度**:$O(n \times 10)$,其中 $n$ 为数组 $nums2$ 的长度。 -- **空间复杂度**:$O(n \times max\underline{}sum)$。 +- **空间复杂度**:$O(n \times max\underline{\hspace{0.5em}}sum)$。 diff --git "a/Solutions/\345\211\221\346\214\207 Offer 51. \346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.md" "b/Solutions/\345\211\221\346\214\207 Offer 51. \346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.md" index 8f62595a..1cdc68c8 100644 --- "a/Solutions/\345\211\221\346\214\207 Offer 51. \346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.md" +++ "b/Solutions/\345\211\221\346\214\207 Offer 51. \346\225\260\347\273\204\344\270\255\347\232\204\351\200\206\345\272\217\345\257\271.md" @@ -43,15 +43,15 @@ 1. 使用全局变量 $cnt$ 来存储逆序对的个数。然后进行归并排序。 2. **分割过程**:先递归地将当前序列平均分成两半,直到子序列长度为 $1$。 - 1. 找到序列中心位置 $mid$,从中心位置将序列分成左右两个子序列 $left\underline{}arr$、$right\underline{}arr$。 - 2. 对左右两个子序列 $left\underline{}arr$、$right\underline{}arr$ 分别进行递归分割。 + 1. 找到序列中心位置 $mid$,从中心位置将序列分成左右两个子序列 $left\underline{\hspace{0.5em}}arr$、$right\underline{\hspace{0.5em}}arr$。 + 2. 对左右两个子序列 $left\underline{\hspace{0.5em}}arr$、$right\underline{\hspace{0.5em}}arr$ 分别进行递归分割。 3. 最终将数组分割为 $n$ 个长度均为 $1$ 的有序子序列。 3. **归并过程**:从长度为 $1$ 的有序子序列开始,依次进行两两归并,直到合并成一个长度为 $n$ 的有序序列。 1. 使用数组变量 $arr$ 存放归并后的有序数组。 - 2. 使用两个指针 $left\underline{}i$、$right\underline{}i$ 分别指向两个有序子序列 $left\underline{}arr$、$right\underline{}arr$ 的开始位置。 + 2. 使用两个指针 $left\underline{\hspace{0.5em}}i$、$right\underline{\hspace{0.5em}}i$ 分别指向两个有序子序列 $left\underline{\hspace{0.5em}}arr$、$right\underline{\hspace{0.5em}}arr$ 的开始位置。 3. 比较两个指针指向的元素: - 1. 如果 $left\underline{}arr[left\underline{}i] \le right\underline{}arr[right\underline{}i]$,则将 $left\underline{}arr[left\underline{}i]$ 存入到结果数组 $arr$ 中,并将指针移动到下一位置。 - 2. 如果 $left\underline{}arr[left\underline{}i] > right\underline{}arr[right\underline{}i]$,则 **记录当前左子序列中元素与当前右子序列元素所形成的逆序对的个数,并累加到 $cnt$ 中,即 `self.cnt += len(left_arr) - left_i`**,然后将 $right\underline{}arr[right\underline{}i]$ 存入到结果数组 $arr$ 中,并将指针移动到下一位置。 + 1. 如果 $left\underline{\hspace{0.5em}}arr[left\underline{\hspace{0.5em}}i] \le right\underline{\hspace{0.5em}}arr[right\underline{\hspace{0.5em}}i]$,则将 $left\underline{\hspace{0.5em}}arr[left\underline{\hspace{0.5em}}i]$ 存入到结果数组 $arr$ 中,并将指针移动到下一位置。 + 2. 如果 $left\underline{\hspace{0.5em}}arr[left\underline{\hspace{0.5em}}i] > right\underline{\hspace{0.5em}}arr[right\underline{\hspace{0.5em}}i]$,则 **记录当前左子序列中元素与当前右子序列元素所形成的逆序对的个数,并累加到 $cnt$ 中,即 `self.cnt += len(left_arr) - left_i`**,然后将 $right\underline{\hspace{0.5em}}arr[right\underline{\hspace{0.5em}}i]$ 存入到结果数组 $arr$ 中,并将指针移动到下一位置。 4. 重复步骤 $3$,直到某一指针到达子序列末尾。 5. 将另一个子序列中的剩余元素存入到结果数组 $arr$ 中。 6. 返回归并后的有序数组 $arr$。