From 2876ed016e7f6de9d36651b58d65f5b455473208 Mon Sep 17 00:00:00 2001 From: ITCharge Date: Mon, 11 Sep 2023 18:09:51 +0800 Subject: [PATCH] =?UTF-8?q?=20=E6=9B=B4=E6=96=B0=E9=A2=98=E8=A7=A3?= =?UTF-8?q?=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...11\346\225\260\344\271\213\345\222\214.md" | 16 +++--- ...73\351\231\244\345\205\203\347\264\240.md" | 12 ++-- ...22\345\272\217\346\225\260\347\273\204.md" | 32 +++++------ ...22\345\205\245\344\275\215\347\275\256.md" | 14 ++--- ...346\227\213\347\237\251\351\230\265 II.md" | 20 +++++-- ...04\345\271\263\346\226\271\346\240\271.md" | 4 +- ...51\351\230\265\347\275\256\351\233\266.md" | 57 +++++++++++++++---- ...351\207\215\345\244\215\351\241\271 II.md" | 21 ++++--- ...04\346\234\200\345\260\217\345\200\274.md" | 10 ++-- ...11\345\272\217\346\225\260\347\273\204.md" | 10 ++-- ...45\244\215\345\205\203\347\264\240 III.md" | 2 +- ...04\347\232\204\344\271\230\347\247\257.md" | 43 ++++++++++++-- ...57\347\232\204\347\211\210\346\234\254.md" | 8 +-- ...54\345\255\227\347\254\246\344\270\262.md" | 11 ++-- ...03\351\237\263\345\255\227\346\257\215.md" | 42 ++++++++++++-- ...60\345\255\227\345\244\247\345\260\217.md" | 17 ++++-- ...1 \347\232\204\344\270\252\346\225\260.md" | 47 ++++++++++++--- ...\345\271\263\345\235\207\346\225\260 I.md" | 51 +++++++++++++---- ...22\345\242\236\345\272\217\345\210\227.md" | 42 ++++++++------ ...14\345\210\206\346\237\245\346\211\276.md" | 23 ++++---- ...77\346\214\211\351\224\256\345\205\245.md" | 55 ++++++++++++++---- ...47\232\204\344\270\252\346\225\260 III.md" | 17 +++--- ...71\347\232\204\350\203\275\345\212\233.md" | 10 ++-- 23 files changed, 393 insertions(+), 171 deletions(-) diff --git "a/Solutions/0015. \344\270\211\346\225\260\344\271\213\345\222\214.md" "b/Solutions/0015. \344\270\211\346\225\260\344\271\213\345\222\214.md" index 1fbcc13b..ed5e3df7 100644 --- "a/Solutions/0015. \344\270\211\346\225\260\344\271\213\345\222\214.md" +++ "b/Solutions/0015. \344\270\211\346\225\260\344\271\213\345\222\214.md" @@ -5,9 +5,9 @@ ## 题目大意 -**描述**:给定一个整数数组 `nums`。 +**描述**:给定一个整数数组 $nums$。 -**要求**:判断 `nums` 中是否存在三个元素 `a`、`b`、`c`,满足 `a + b + c == 0`。要求找出所有满足要求的不重复的三元组。 +**要求**:判断 $nums$ 中是否存在三个元素 $a$、$b$、$c$,满足 $a + b + c == 0$。要求找出所有满足要求的不重复的三元组。 **说明**: @@ -34,15 +34,15 @@ ### 思路 1:对撞指针 -直接三重遍历查找 `a`、`b`、`c` 的时间复杂度是:$O(n^3)$。我们可以通过一些操作来降低复杂度。 +直接三重遍历查找 $a$、$b$、$c$ 的时间复杂度是:$O(n^3)$。我们可以通过一些操作来降低复杂度。 -先将数组进行排序,以保证按顺序查找 `a`、`b`、`c` 时,元素值为升序,从而保证所找到的三个元素是不重复的。同时也方便下一步使用双指针减少一重遍历。时间复杂度为:$O(nlogn)$。 +先将数组进行排序,以保证按顺序查找 $a$、$b$、$c$ 时,元素值为升序,从而保证所找到的三个元素是不重复的。同时也方便下一步使用双指针减少一重遍历。时间复杂度为:$O(nlogn)$。 -第一重循环遍历 `a`,对于每个 `a` 元素,从 `a` 元素的下一个位置开始,使用对撞指针 `left`,`right`。`left` 指向 `a` 元素的下一个位置,`right` 指向末尾位置。先将 `left` 右移、`right` 左移去除重复元素,再进行下边的判断。 +第一重循环遍历 $a$,对于每个 $a$ 元素,从 $a$ 元素的下一个位置开始,使用对撞指针 $left$,$right$。$left$ 指向 $a$ 元素的下一个位置,$right$ 指向末尾位置。先将 $left$ 右移、$right$ 左移去除重复元素,再进行下边的判断。 -1. 如果 `nums[a] + nums[left] + nums[right] = 0`,则得到一个解,将其加入答案数组中,并继续将 `left` 右移,`right` 左移; -2. 如果 `nums[a] + nums[left] + nums[right] > 0`,说明 `nums[right]` 值太大,将 `right` 向左移; -3. 如果 `nums[a] + nums[left] + nums[right] < 0`,说明 `nums[left]` 值太小,将 `left` 右移。 +1. 如果 $nums[a] + nums[left] + nums[right] == 0$,则得到一个解,将其加入答案数组中,并继续将 $left$ 右移,$right$ 左移; +2. 如果 $nums[a] + nums[left] + nums[right] > 0$,说明 $nums[right]$ 值太大,将 $right$ 向左移; +3. 如果 $nums[a] + nums[left] + nums[right] < 0$,说明 $nums[left]$ 值太小,将 $left$ 右移。 ### 思路 1:代码 diff --git "a/Solutions/0027. \347\247\273\351\231\244\345\205\203\347\264\240.md" "b/Solutions/0027. \347\247\273\351\231\244\345\205\203\347\264\240.md" index 65dbc1f1..81e6d495 100644 --- "a/Solutions/0027. \347\247\273\351\231\244\345\205\203\347\264\240.md" +++ "b/Solutions/0027. \347\247\273\351\231\244\345\205\203\347\264\240.md" @@ -5,9 +5,9 @@ ## 题目大意 -**描述**:给定一个数组 `nums`,和一个值 `val`。 +**描述**:给定一个数组 $nums$,和一个值 $val$。 -**要求**:不使用额外数组空间,将数组中所有数值等于 `val` 值的元素移除掉,并且返回新数组的长度。 +**要求**:不使用额外数组空间,将数组中所有数值等于 $val$ 值的元素移除掉,并且返回新数组的长度。 **说明**: @@ -37,10 +37,10 @@ ### 思路 1:快慢指针 -1. 使用两个指针 `slow`,`fast`。`slow` 指向处理好的非 `val` 值元素数组的尾部,`fast` 指针指向当前待处理元素。 -2. 不断向右移动 `fast` 指针,每次移动到非 `val` 值的元素,则将左右指针对应的数交换,交换同时将 `slow` 右移。 -3. 这样就将非 `val` 值的元素进行前移,`slow` 指针左边均为处理好的非 `val` 值元素,而从 `slow` 指针指向的位置开始, `fast` 指针左边都为 `val `值。 -4. 遍历结束之后,则所有 `val` 值元素都移动到了右侧,且保持了非零数的相对位置。此时 `slow` 就是新数组的长度。 +1. 使用两个指针 $slow$,$fast$。$slow$ 指向处理好的非 $val$ 值元素数组的尾部,$fast$ 指针指向当前待处理元素。 +2. 不断向右移动 $fast$ 指针,每次移动到非 $val$ 值的元素,则将左右指针对应的数交换,交换同时将 $slow$ 右移。 +3. 这样就将非 $val$ 值的元素进行前移,$slow$ 指针左边均为处理好的非 $val$ 值元素,而从 $slow$ 指针指向的位置开始, $fast$ 指针左边都为 $val $值。 +4. 遍历结束之后,则所有 $val$ 值元素都移动到了右侧,且保持了非零数的相对位置。此时 $slow$ 就是新数组的长度。 ### 思路 1:代码 diff --git "a/Solutions/0033. \346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.md" "b/Solutions/0033. \346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.md" index fa4e55a4..af91e2de 100644 --- "a/Solutions/0033. \346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.md" +++ "b/Solutions/0033. \346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.md" @@ -5,13 +5,13 @@ ## 题目大意 -**描述**:给定一个整数数组 `nums`,数组中值互不相同。给定的 `nums` 是经过升序排列后的又进行了「旋转」操作的。再给定一个整数 `target`。 +**描述**:给定一个整数数组 $nums$,数组中值互不相同。给定的 $nums$ 是经过升序排列后的又进行了「旋转」操作的。再给定一个整数 $target$。 -**要求**:从 `nums` 中找到 `target` 所在位置,如果找到,则返回对应下标,找不到则返回 `-1`。 +**要求**:从 $nums$ 中找到 $target$ 所在位置,如果找到,则返回对应下标,找不到则返回 $-1$。 **说明**: -- 旋转操作:升序排列的数组 nums 在预先未知的第 k 个位置进行了右移操作,变成了 `[nums[k]], nums[k+1], ... , nums[n-1], ... , nums[0], nums[1], ... , nums[k-1]`。 +- 旋转操作:升序排列的数组 nums 在预先未知的第 k 个位置进行了右移操作,变成了 $[nums[k]], nums[k+1], ... , nums[n-1], ... , nums[0], nums[1], ... , nums[k-1]$。 **示例**: @@ -33,7 +33,7 @@ ### 思路 1:二分查找 -原本为升序排列的数组 `nums` 经过「旋转」之后,会有两种情况,第一种就是原先的升序序列,另一种是两段升序的序列。 +原本为升序排列的数组 $nums$ 经过「旋转」之后,会有两种情况,第一种就是原先的升序序列,另一种是两段升序的序列。 ```python * @@ -53,24 +53,24 @@ * ``` -最直接的办法就是遍历一遍,找到目标值 `target`。但是还可以有更好的方法。考虑用二分查找来降低算法的时间复杂度。 +最直接的办法就是遍历一遍,找到目标值 $target$。但是还可以有更好的方法。考虑用二分查找来降低算法的时间复杂度。 我们将旋转后的数组看成左右两个升序部分:左半部分和右半部分。 有人会说第一种情况不是只有一个部分吗?其实我们可以把第一种情况中的整个数组看做是左半部分,然后右半部分为空数组。 -然后创建两个指针 `left`、`right`,分别指向数组首尾。让后计算出两个指针中间值 `mid`。将 `mid` 与两个指针做比较,并考虑与 `target` 的关系。 +然后创建两个指针 $left$、$right$,分别指向数组首尾。让后计算出两个指针中间值 $mid$。将 $mid$ 与两个指针做比较,并考虑与 $target$ 的关系。 -- 如果 `mid[mid] == target`,说明找到了 `target`,直接返回下标。 -- 如果 `nums[mid] ≥ nums[left]`,则 `mid` 在左半部分(因为右半部分值都比 `nums[left]` 小)。 - - 如果 `nums[mid] ≥ target`,并且 `target ≥ nums[left]`,则 `target` 在左半部分,并且在 `mid` 左侧,此时应将 `right` 左移到 `mid - 1` 位置。 - - 否则如果 `nums[mid] ≤ target`,则 `target` 在左半部分,并且在 `mid` 右侧,此时应将 `left` 右移到 `mid + 1` 位置。 - - 否则如果 `nums[left] > target`,则 `target` 在右半部分,应将 `left` 移动到 `mid + 1` 位置。 +- 如果 $mid[mid] == target$,说明找到了 $target$,直接返回下标。 +- 如果 $nums[mid] \ge nums[left]$,则 $mid$ 在左半部分(因为右半部分值都比 $nums[left]$ 小)。 + - 如果 $nums[mid] \ge target$,并且 $target \ge nums[left]$,则 $target$ 在左半部分,并且在 $mid$ 左侧,此时应将 $right$ 左移到 $mid - 1$ 位置。 + - 否则如果 $nums[mid] \le target$,则 $target$ 在左半部分,并且在 $mid$ 右侧,此时应将 $left$ 右移到 $mid + 1$ 位置。 + - 否则如果 $nums[left] > target$,则 $target$ 在右半部分,应将 $left$ 移动到 $mid + 1$ 位置。 -- 如果 `nums[mid] < nums[left]`,则 `mid` 在右半部分(因为右半部分值都比 `nums[left]` 小)。 - - 如果 `nums[mid] < target`,并且 `target ≤ nums[right]`,则 `target` 在右半部分,并且在 `mid` 右侧,此时应将 `left` 右移到 `mid + 1` 位置。 - - 否则如果 `nums[mid] ≥ target`,则 `target` 在右半部分,并且在 `mid` 左侧,此时应将 `right` 左移到 `mid - 1` 位置。 - - 否则如果 `nums[right] < target`,则 `target` 在左半部分,应将 `right` 左移到 `mid - 1` 位置。 +- 如果 $nums[mid] < nums[left]$,则 $mid$ 在右半部分(因为右半部分值都比 $nums[left]$ 小)。 + - 如果 $nums[mid] < target$,并且 $target \le nums[right]$,则 $target$ 在右半部分,并且在 $mid$ 右侧,此时应将 $left$ 右移到 $mid + 1$ 位置。 + - 否则如果 $nums[mid] \ge target$,则 $target$ 在右半部分,并且在 $mid$ 左侧,此时应将 $right$ 左移到 $mid - 1$ 位置。 + - 否则如果 $nums[right] < target$,则 $target$ 在左半部分,应将 $right$ 左移到 $mid - 1$ 位置。 ### 思路 1:代码 @@ -100,6 +100,6 @@ class Solution: ### 思路 1:复杂度分析 -- **时间复杂度**:$O(\log_2 n)$。二分查找算法的时间复杂度为 $O(\log_2 n)$。 +- **时间复杂度**:$O(\log n)$。二分查找算法的时间复杂度为 $O(\log n)$。 - **空间复杂度**:$O(1)$。只用到了常数空间存放若干变量。 diff --git "a/Solutions/0035. \346\220\234\347\264\242\346\217\222\345\205\245\344\275\215\347\275\256.md" "b/Solutions/0035. \346\220\234\347\264\242\346\217\222\345\205\245\344\275\215\347\275\256.md" index 6f2dce70..e1de1996 100644 --- "a/Solutions/0035. \346\220\234\347\264\242\346\217\222\345\205\245\344\275\215\347\275\256.md" +++ "b/Solutions/0035. \346\220\234\347\264\242\346\217\222\345\205\245\344\275\215\347\275\256.md" @@ -5,7 +5,7 @@ ## 题目大意 -**描述**:给定一个排好序的数组 `nums`,以及一个目标值 `target`。 +**描述**:给定一个排好序的数组 $nums$,以及一个目标值 $target$。 **要求**:在数组中找到目标值,并返回下标。如果找不到,则返回目标值按顺序插入数组的位置。 @@ -29,15 +29,15 @@ ### 思路 1:二分查找 -设定左右节点为数组两端,即 `left = 0`,`right = len(nums) - 1`,代表待查找区间为 `[left, right]`(左闭右闭)。 +设定左右节点为数组两端,即 `left = 0`,`right = len(nums) - 1`,代表待查找区间为 $[left, right]$(左闭右闭)。 -取两个节点中心位置 `mid`,先比较中心位置值 `nums[mid]` 与目标值 `target` 的大小。 +取两个节点中心位置 $mid$,先比较中心位置值 $nums[mid]$ 与目标值 $target$ 的大小。 -- 如果中心位置值 `nums[mid]` 与目标值 `target` 相等,则当前中心位置为待插入数组的位置。 -- 如果中心位置值 `nums[mid]` 小于目标值 `target`,则将左节点设置为 `mid + 1`,然后继续在右区间 `[mid + 1, right]` 搜索。 -- 如果中心位置值 `nums[mid]` 大于目标值 `target`,则将右节点设置为 `mid - 1`,然后继续在左区间 `[left, mid - 1]` 搜索。 +- 如果 $target == nums[mid]$,则当前中心位置为待插入数组的位置。 +- 如果 $target > nums[mid]$,则将左节点设置为 $mid + 1$,然后继续在右区间 $[mid + 1, right]$ 搜索。 +- 如果 $target < nums[mid]$,则将右节点设置为 $mid - 1$,然后继续在左区间 $[left, mid - 1]$ 搜索。 -直到查找到目标值返回待插入数组的位置,或者等到 `left > right` 时停止查找,此时 `left` 所在位置就是待插入数组的位置。 +直到查找到目标值返回待插入数组的位置,或者等到 $left > right$ 时停止查找,此时 $left$ 所在位置就是待插入数组的位置。 ### 思路 1:二分查找代码 diff --git "a/Solutions/0059. \350\236\272\346\227\213\347\237\251\351\230\265 II.md" "b/Solutions/0059. \350\236\272\346\227\213\347\237\251\351\230\265 II.md" index 8f98d159..d8090d19 100644 --- "a/Solutions/0059. \350\236\272\346\227\213\347\237\251\351\230\265 II.md" +++ "b/Solutions/0059. \350\236\272\346\227\213\347\237\251\351\230\265 II.md" @@ -5,17 +5,22 @@ ## 题目大意 -给你一个正整数 `n`。 +给你一个正整数 $n$。 -要求:生成一个包含 `1` 到 $n^2$ 所有元素,且元素按顺时针顺序螺旋排列的 `n x n` 正方形矩阵 `matrix` 。 +要求:生成一个包含 $1 \sim n^2$ 的所有元素,且元素按顺时针顺序螺旋排列的 $n \times n$ 正方形矩阵 $matrix$。 ## 解题思路 -这道题跟「[54. 螺旋矩阵](https://leetcode.cn/problems/spiral-matrix/)」思路是一样的。定义上、下、左、右的边界,然后按照逆时针的顺序从边界上依次给数组相应位置赋值。 +### 思路 1:模拟 -当访问完当前边界之后,要更新一下边界位置,缩小范围,方便下一轮进行访问。 +这道题跟「[54. 螺旋矩阵](https://leetcode.cn/problems/spiral-matrix/)」思路是一样的。 -## 代码 +1. 构建一个 $n \times n$ 大小的数组 $matrix$ 存储答案。然后定义一下上、下、左、右的边界。 +2. 然后按照逆时针的顺序从边界上依次给数组 $matrix$ 相应位置赋值。 +3. 当访问完当前边界之后,要更新一下边界位置,缩小范围,方便下一轮进行访问。 +4. 最后返回 $matrix$。 + +### 思路 1:代码 ```python class Solution: @@ -51,3 +56,8 @@ class Solution: return matrix ``` +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n^2)$。 +- **空间复杂度**:$O(n^2)$。 + diff --git "a/Solutions/0069. x \347\232\204\345\271\263\346\226\271\346\240\271.md" "b/Solutions/0069. x \347\232\204\345\271\263\346\226\271\346\240\271.md" index d4d58368..8359af6a 100644 --- "a/Solutions/0069. x \347\232\204\345\271\263\346\226\271\346\240\271.md" +++ "b/Solutions/0069. x \347\232\204\345\271\263\346\226\271\346\240\271.md" @@ -5,7 +5,7 @@ ## 题目大意 -**要求**:实现 `int sqrt(int x)` 函数。计算并返回 `x` 的平方根(只保留整数部分),其中 `x` 是非负整数。 +**要求**:实现 `int sqrt(int x)` 函数。计算并返回 $x$ 的平方根(只保留整数部分),其中 $x$ 是非负整数。 **说明**: @@ -32,7 +32,7 @@ ### 思路 1:二分查找 -因为求解的是 `x` 开方的整数部分。所以我们可以从 `0` ~ `x` 的范围进行遍历,找到 $k^2 \le x$ 的最大结果。 +因为求解的是 $x$ 开方的整数部分。所以我们可以从 $0 \sim x$ 的范围进行遍历,找到 $k^2 \le x$ 的最大结果。 为了减少算法的时间复杂度,我们使用二分查找的方法来搜索答案。 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 998dfb93..634bd106 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" @@ -5,27 +5,57 @@ ## 题目大意 -给定一个 `m * n` 大小的矩阵。 +**描述**:给定一个 $m \times n$ 大小的矩阵 $matrix$。 -要求:如果一个元素为 `0`,则将其所在行和列所有元素都置为 `0`。要求使用原地算法,并使用常量空间解决。 +**要求**:如果一个元素为 $0$,则将其所在行和列所有元素都置为 $0$。 -## 解题思路 +**说明**: + +- 请使用「原地」算法。 +- $m == matrix.length$。 +- $n == matrix[0].length$。 +- $1 \le m, n \le 200$。 +- $-2^{31} \le matrix[i][j] \le 2^{31} - 1$。 +- **进阶**: + - 一个直观的解决方案是使用 $O(m \times n)$ 的额外空间,但这并不是一个好的解决方案。 + - 一个简单的改进方案是使用 $O(m + n)$ 的额外空间,但这仍然不是最好的解决方案。 + - 你能想出一个仅使用常量空间的解决方案吗? + + +**示例**: + +- 示例 1: +- ![](https://assets.leetcode.com/uploads/2020/08/17/mat1.jpg) + +```python +输入:matrix = [[1,1,1],[1,0,1],[1,1,1]] +输出:[[1,0,1],[0,0,0],[1,0,1]] +``` -直观上可以使用两个数组来标记行和列出现 `0` 的情况,但这样空间复杂度就是 $O(m+n)$ 了,不符合题意。 +- 示例 2: -考虑使用数组原本的元素进行记录出现 `0` 的情况。 +![](https://assets.leetcode.com/uploads/2020/08/17/mat2.jpg) -设定两个变量 `flag_row0`、`flag_col0` 来标记第一行、第一列是否出现了 `0`。 +``` +输入:matrix = [[1,1,1],[1,0,1],[1,1,1]] +输出:[[1,0,1],[0,0,0],[1,0,1]] +``` -接下来我们使用数组第一行、第一列来标记 `0` 的情况。 +## 解题思路 -对数组除第一行、第一列之外的每个元素进行遍历,如果某个元素出现 `0` 了,则使用数组的第一行、第一列对应位置来存储 `0` 的标记。 +### 思路 1:使用标记变量 -再对数组除第一行、第一列之外的每个元素进行遍历,通过对第一行、第一列的标记 `0` 情况,进行置为 `0` 的操作。 +直观上可以使用两个数组来标记行和列出现 $0$ 的情况,但这样空间复杂度就是 $O(m+n)$ 了,不符合题意。 -然后再根据 `flag_row0`、`flag_col0` 的标记情况,对第一行、第一列进行置为 `0` 的操作。 +考虑使用数组原本的元素进行记录出现 $0$ 的情况。 -## 代码 +1. 设定两个变量 $flag\underline{}row0$、$flag\underline{}col0$ 来标记第一行、第一列是否出现了 $0$。 +2. 接下来我们使用数组第一行、第一列来标记 $0$ 的情况。 +3. 对数组除第一行、第一列之外的每个元素进行遍历,如果某个元素出现 $0$ 了,则使用数组的第一行、第一列对应位置来存储 $0$ 的标记。 +4. 再对数组除第一行、第一列之外的每个元素进行遍历,通过对第一行、第一列的标记 $0$ 情况,进行置为 $0$ 的操作。 +5. 最后再根据 $flag\underline{}row0$、$flag\underline{}col0$ 的标记情况,对第一行、第一列进行置为 $0$ 的操作。 + +### 思路 1:代码 ```python class Solution: @@ -63,3 +93,8 @@ class Solution: matrix[0][j] = 0 ``` +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(m \times n)$。 +- **空间复杂度**:$O(1)$。 + diff --git "a/Solutions/0080. \345\210\240\351\231\244\346\234\211\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\351\207\215\345\244\215\351\241\271 II.md" "b/Solutions/0080. \345\210\240\351\231\244\346\234\211\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\351\207\215\345\244\215\351\241\271 II.md" index 749be212..558ab094 100644 --- "a/Solutions/0080. \345\210\240\351\231\244\346\234\211\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\351\207\215\345\244\215\351\241\271 II.md" +++ "b/Solutions/0080. \345\210\240\351\231\244\346\234\211\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\351\207\215\345\244\215\351\241\271 II.md" @@ -5,15 +5,15 @@ ## 题目大意 -**描述**:给定一个有序数组 `nums`。 +**描述**:给定一个有序数组 $nums$。 -**要求**:在原数组空间基础上删除重复出现 `2` 次以上的元素,并返回删除后数组的新长度。 +**要求**:在原数组空间基础上删除重复出现 $2$ 次以上的元素,并返回删除后数组的新长度。 **说明**: - $1 \le nums.length \le 3 * 10^4$。 - $-10^4 \le nums[i] \le 10^4$。 -- `nums` 已按升序排列。 +- $nums$ 已按升序排列。 **示例**: @@ -39,12 +39,12 @@ 因为数组是有序的,所以重复元素必定是连续的。可以使用快慢指针来解决。具体做法如下: -1. 使用两个指针 `slow`,`fast`。`slow` 指针指向即将放置元素的位置,`fast` 指针指向当前待处理元素。 -2. 本题要求相同元素最多出现 2 次,并且 `slow - 2` 是上上次放置了元素的位置。则应该检查 `nums[slow - 2]` 和当前待处理元素 `nums[fast]` 是否相同。 - 1. 如果 `nums[slow - 2] == nums[fast]` 时,此时必有 `nums[slow - 2] == nums[slow - 1] == nums[fast]`,则当前 `nums[fast]` 不保留,直接向右移动快指针 `fast`。 - 2. 如果 `nums[slow - 2] != nums[fast]` 时,则保留 `nums[fast]`。将 `nums[fast]` 赋值给 `nums[slow]` ,同时将 `slow` 右移。然后再向右移动快指针 `fast`。 -3. 这样 `slow` 指针左边均为处理好的数组元素,而从 `slow` 指针指向的位置开始, `fast` 指针左边都为舍弃的重复元素。 -4. 遍历结束之后,此时 `slow` 就是新数组的长度。 +1. 使用两个指针 $slow$,$fast$。$slow$ 指针指向即将放置元素的位置,$fast$ 指针指向当前待处理元素。 +2. 本题要求相同元素最多出现 $2$ 次,并且 $slow - 2$ 是上上次放置了元素的位置。则应该检查 $nums[slow - 2]$ 和当前待处理元素 $nums[fast]$ 是否相同。 + 1. 如果 $nums[slow - 2] == nums[fast]$ 时,此时必有 $nums[slow - 2] == nums[slow - 1] == nums[fast]$,则当前 $nums[fast]$ 不保留,直接向右移动快指针 $fast$。 + 2. 如果 $nums[slow - 2] \ne nums[fast]$ 时,则保留 $nums[fast]$。将 $nums[fast]$ 赋值给 $nums[slow]$ ,同时将 $slow$ 右移。然后再向右移动快指针 $fast$。 +3. 这样 $slow$ 指针左边均为处理好的数组元素,而从 $slow$ 指针指向的位置开始, $fast$ 指针左边都为舍弃的重复元素。 +4. 遍历结束之后,此时 $slow$ 就是新数组的长度。 ### 思路 1:代码 @@ -66,5 +66,4 @@ class Solution: ### 思路 1:复杂度分析 - **时间复杂度**:$O(n)$。 -- **空间复杂度**:$O(1)$。 - +- **空间复杂度**:$O(1)$。 \ No newline at end of file diff --git "a/Solutions/0153. \345\257\273\346\211\276\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\346\234\200\345\260\217\345\200\274.md" "b/Solutions/0153. \345\257\273\346\211\276\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\346\234\200\345\260\217\345\200\274.md" index 17d589eb..e9f721d7 100644 --- "a/Solutions/0153. \345\257\273\346\211\276\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\346\234\200\345\260\217\345\200\274.md" +++ "b/Solutions/0153. \345\257\273\346\211\276\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\232\204\346\234\200\345\260\217\345\200\274.md" @@ -5,7 +5,7 @@ ## 题目大意 -**描述**:给定一个数组 `nums`,`nums` 是有升序数组经过「旋转」得到的。但是旋转次数未知。数组中不存在重复元素。 +**描述**:给定一个数组 $nums$,$nums$ 是有升序数组经过「旋转」得到的。但是旋转次数未知。数组中不存在重复元素。 **要求**:找出数组中的最小元素。 @@ -64,10 +64,10 @@ 最直接的办法就是遍历一遍,找到最小值。但是还可以有更好的方法。考虑用二分查找来降低算法的时间复杂度。 -创建两个指针 `left`、`right`,分别指向数组首尾。让后计算出两个指针中间值 `mid`。将 `mid` 与两个指针做比较。 +创建两个指针 $left$、$right$,分别指向数组首尾。让后计算出两个指针中间值 $mid$。将 $mid$ 与两个指针做比较。 -1. 如果 `nums[mid] > nums[right]`,则最小值不可能在 `mid` 左侧,一定在 `mid` 右侧,则将 `left` 移动到 `mid + 1` 位置,继续查找右侧区间。 -2. 如果 `nums[mid] ≤ nums[right]`,则最小值一定在 `mid` 左侧,或者 `mid` 位置,将 `right` 移动到 `mid` 位置上,继续查找左侧区间。 +1. 如果 $nums[mid] > nums[right]$,则最小值不可能在 $mid$ 左侧,一定在 $mid$ 右侧,则将 $left$ 移动到 $mid + 1$ 位置,继续查找右侧区间。 +2. 如果 $nums[mid] \le nums[right]$,则最小值一定在 $mid$ 左侧,或者 $mid$ 位置,将 $right$ 移动到 $mid$ 位置上,继续查找左侧区间。 ### 思路 1:代码 @@ -87,6 +87,6 @@ class Solution: ### 思路 1:复杂度分析 -- **时间复杂度**:$O(\log_2 n)$。二分查找算法的时间复杂度为 $O(\log_2 n)$。 +- **时间复杂度**:$O(\log n)$。二分查找算法的时间复杂度为 $O(\log n)$。 - **空间复杂度**:$O(1)$。只用到了常数空间存放若干变量。 diff --git "a/Solutions/0167. \344\270\244\346\225\260\344\271\213\345\222\214 II - \350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.md" "b/Solutions/0167. \344\270\244\346\225\260\344\271\213\345\222\214 II - \350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.md" index 06167ce6..920bb750 100644 --- "a/Solutions/0167. \344\270\244\346\225\260\344\271\213\345\222\214 II - \350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.md" +++ "b/Solutions/0167. \344\270\244\346\225\260\344\271\213\345\222\214 II - \350\276\223\345\205\245\346\234\211\345\272\217\346\225\260\347\273\204.md" @@ -11,7 +11,7 @@ **说明**: -- $2 \le numbers.length \le 3 * 10^4$。 +- $2 \le numbers.length \le 3 \times 10^4$。 - $-1000 \le numbers[i] \le 1000$。 - $numbers$ 按非递减顺序排列。 - $-1000 \le target \le 1000$。 @@ -24,7 +24,7 @@ ```python 输入:numbers = [2,7,11,15], target = 9 输出:[1,2] -解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。 +解释:2 与 7 之和等于目标数 9。因此 index1 = 1, index2 = 2。返回 [1, 2]。 ``` - 示例 2: @@ -32,7 +32,7 @@ ```python 输入:numbers = [2,3,4], target = 6 输出:[1,3] -解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。 +解释:2 与 4 之和等于目标数 6。因此 index1 = 1, index2 = 3。返回 [1, 3]。 ``` ## 解题思路 @@ -61,7 +61,7 @@ class Solution: 3. 使用两个指针 $left$,$right$。$left$ 指向数组第一个数的下一个数,$right$ 指向数组值最大元素位置。 4. 判断第一个数 $numsbers[i]$ 和两个指针中间元素 $numbers[mid]$ 的和与目标值的关系。 1. 如果 $numbers[mid] + numbers[i] < target$,排除掉不可能区间 $[left, mid]$,在 $[mid + 1, right]$ 中继续搜索。 - 2. 如果 $numbers[mid] + numbers[i] >= target$,则第二个数可能在 $[left, mid]$ 中,则在 $[left, mid]$ 中继续搜索。 + 2. 如果 $numbers[mid] + numbers[i] \ge target$,则第二个数可能在 $[left, mid]$ 中,则在 $[left, mid]$ 中继续搜索。 5. 直到 $left$ 和 $right$ 移动到相同位置停止检测。如果 $numbers[left] + numbers[i] == target$,则返回两个元素位置 $[left + 1, i + 1]$(下标从 $1$ 开始计数)。 6. 如果最终仍没找到,则返回 $[-1, -1]$。 @@ -86,7 +86,7 @@ class Solution: ### 思路 1:复杂度分析 -- **时间复杂度**:$O(n \times \log_2 n)$。 +- **时间复杂度**:$O(n \times \log n)$。 - **空间复杂度**:$O(1)$。 ### 思路 2:对撞指针 diff --git "a/Solutions/0220. \345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240 III.md" "b/Solutions/0220. \345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240 III.md" index 7b556d30..dc9b1145 100644 --- "a/Solutions/0220. \345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240 III.md" +++ "b/Solutions/0220. \345\255\230\345\234\250\351\207\215\345\244\215\345\205\203\347\264\240 III.md" @@ -108,7 +108,7 @@ class Solution: 1. 使用二分查找算法,查找 $nums[right]$ 在 $window$ 中的位置 $idx$。 2. 判断 $window[idx]$ 与相邻位置上元素差值绝对值,若果满足 $abs(window[idx] - window[idx - 1]) \le t$ 或者 $abs(window[idx + 1] - window[idx]) \le t$ 时返回 `True`。 6. 向右移动 $right$。 -7. 重复 $3$ ~ $6$ 步,直到 $right$ 到达数组末尾,如果还没找到满足条件的情况,则返回 `False`。 +7. 重复 $3 \sim 6$ 步,直到 $right$ 到达数组末尾,如果还没找到满足条件的情况,则返回 `False`。 ### 思路 2:代码 diff --git "a/Solutions/0238. \351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.md" "b/Solutions/0238. \351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.md" index 6fbbb30a..bfce1bb4 100644 --- "a/Solutions/0238. \351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.md" +++ "b/Solutions/0238. \351\231\244\350\207\252\350\272\253\344\273\245\345\244\226\346\225\260\347\273\204\347\232\204\344\271\230\347\247\257.md" @@ -5,15 +5,43 @@ ## 题目大意 -给定一个数组 nums。要求输出数组 output,其中 output[i] 为数组 nums 中除了 nums[i] 之外的其他所有元素乘积。 +**描述**:给定一个数组 nums。 -要求不能使用除法,且在 O(n) 时间复杂度、常数空间复杂度内解决问题。 +**要求**:返回数组 $answer$,其中 $answer[i]$ 等于 $nums$ 中除 $nums[i]$ 之外其余各元素的乘积。 + +**说明**: + +- 题目数据保证数组 $nums$ 之中任意元素的全部前缀元素和后缀的乘积都在 $32$ 位整数范围内。 +- 请不要使用除法,且在 $O(n)$ 时间复杂度内解决问题。 +- **进阶**:在 $O(1)$ 的额外空间复杂度内完成这个题目。 +- $2 \le nums.length \le 10^5$。 +- $-30 \le nums[i] \le 30$。 + +**示例**: + +- 示例 1: + +```python +输入: nums = [1,2,3,4] +输出: [24,12,8,6] +``` + +- 示例 2: + +```python +输入: nums = [-1,1,0,-3,3] +输出: [0,0,9,0,0] +``` ## 解题思路 -构造一个答案数组 res,长度和数组 nums 长度一致。先从左到右遍历一遍 nums 数组,将 nums[i] 左侧的元素乘积累积起来,存储到 res 数组中。再从右到左遍历一遍,将 nums[i] 右侧的元素乘积累积起来,再乘以原本 res[i] 的值,即为 nums 中除了 nums[i] 之外的其他所有元素乘积。 +### 思路 1:两次遍历 + +1. 构造一个答案数组 $res$,长度和数组 $nums$ 长度一致。 +2. 先从左到右遍历一遍 $nums$ 数组,将 $nums[i]$ 左侧的元素乘积累积起来,存储到 $res$ 数组中。 +3. 再从右到左遍历一遍,将 $nums[i]$ 右侧的元素乘积累积起来,再乘以原本 $res[i]$ 的值,即为 $nums$ 中除了 $nums[i]$ 之外的其他所有元素乘积。 -## 代码 +### 思路 1:代码 ```python class Solution: @@ -33,3 +61,10 @@ class Solution: return res ``` +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$。 +- **空间复杂度**:$O(1)$。 + + + diff --git "a/Solutions/0278. \347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.md" "b/Solutions/0278. \347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.md" index b9d22bd0..504f17dd 100644 --- "a/Solutions/0278. \347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.md" +++ "b/Solutions/0278. \347\254\254\344\270\200\344\270\252\351\224\231\350\257\257\347\232\204\347\211\210\346\234\254.md" @@ -5,9 +5,9 @@ ## 题目大意 -**描述**:给你一个整数 `n`,代表已经发布的版本号。还有一个用于检测版本是否出错的接口 `isBadVersion(version):` 。 +**描述**:给你一个整数 $n$,代表已经发布的版本号。还有一个用于检测版本是否出错的接口 `isBadVersion(version):` 。 -**要求**:找出第一次出错的版本号 `bad`。 +**要求**:找出第一次出错的版本号 $bad$。 **说明**: @@ -41,7 +41,7 @@ 题目要求尽可能减少对 `isBadVersion(version):` 接口的调用,所以不能对每个版本都调用接口,而是应该将接口调用的次数降到最低。 -可以注意到:如果检测某个版本不是错误版本时,则该版本之前的所有版本都不是错误版本。而当某个版本是错误版本时,则该版本之后的所有版本都是错误版本。我们可以利用这样的性质,在 `[1, n]` 的区间内使用二分查找方法,从而在 $O(\log_2n)$ 次内找到第一个出错误的版本。 +可以注意到:如果检测某个版本不是错误版本时,则该版本之前的所有版本都不是错误版本。而当某个版本是错误版本时,则该版本之后的所有版本都是错误版本。我们可以利用这样的性质,在 $[1, n]$ 的区间内使用二分查找方法,从而在 $O(\log n)$ 时间复杂度内找到第一个出错误的版本。 ### 思路 1:代码 @@ -61,6 +61,6 @@ class Solution: ### 思路 1:复杂度分析 -- **时间复杂度**:$O(\log_2 n)$。二分查找算法的时间复杂度为 $O(\log_2 n)$。 +- **时间复杂度**:$O(\log n)$。二分查找算法的时间复杂度为 $O(\log n)$。 - **空间复杂度**:$O(1)$。只用到了常数空间存放若干变量。 diff --git "a/Solutions/0344. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.md" "b/Solutions/0344. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.md" index 492f1249..4aa3b7ab 100644 --- "a/Solutions/0344. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.md" +++ "b/Solutions/0344. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262.md" @@ -5,7 +5,7 @@ ## 题目大意 -**描述**:给定一个字符数组 `s`。 +**描述**:给定一个字符数组 $s$。 **要求**:将其反转。 @@ -13,7 +13,7 @@ - 不能使用额外的数组空间,必须原地修改输入数组、使用 $O(1)$ 的额外空间解决问题。 - $1 \le s.length \le 10^5$。 -- `s[i]` 都是 ASCII 码表中的可打印字符。 +- $s[i]$ 都是 ASCII 码表中的可打印字符。 **示例**: @@ -35,9 +35,9 @@ ### 思路 1:对撞指针 -1. 使用两个指针 `left`,`right`。`left` 指向字符数组开始位置,`right` 指向字符数组结束位置。 -2. 交换 `s[left]` 和 `s[right]`,将 `left` 右移、`right` 左移。 -3. 如果遇到 `left == right`,跳出循环。 +1. 使用两个指针 $left$,$right$。$left$ 指向字符数组开始位置,$right$ 指向字符数组结束位置。 +2. 交换 $s[left]$ 和 $s[right]$,将 $left$ 右移、$right$ 左移。 +3. 如果遇到 $left == right$,跳出循环。 ### 思路 1:代码 @@ -55,4 +55,3 @@ class Solution: - **时间复杂度**:$O(n)$。 - **空间复杂度**:$O(1)$。 - diff --git "a/Solutions/0345. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.md" "b/Solutions/0345. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.md" index 042e7039..016f26e0 100644 --- "a/Solutions/0345. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.md" +++ "b/Solutions/0345. \345\217\215\350\275\254\345\255\227\347\254\246\344\270\262\344\270\255\347\232\204\345\205\203\351\237\263\345\255\227\346\257\215.md" @@ -5,14 +5,44 @@ ## 题目大意 -给定一个字符串 s,将字符串中的元音字母进行反转。 +**描述**:给定一个字符串 $s$。 + +**要求**:将字符串中的元音字母进行反转。 + +**说明**: + +- 元音字母包括 `'a'`、`'e'`、`'i'`、`'o'`、`'u'`,且可能以大小写两种形式出现不止一次。 +- $1 \le s.length \le 3 \times 10^5$。 +- $s$ 由可打印的 ASCII 字符组成。 + +**示例**: + +- 示例 1: + +```python +输入:s = "hello" +输出:"holle" +``` + +- 示例 2: + +```python +输入:s = "leetcode" +输出:"leotcede" +``` ## 解题思路 -因为 Python 的字符串是不可变的,所以我们先将字符串转为数组。 -然后利用两个指针 left,right。一个从左到右移动查找元音字母,一个从右到左查找元音字母。如果都找到了,则交换字符,然后继续进行查找。直到两个指针指向相同位置时停止。最后返回对应的字符串即可。 +### 思路 1:对撞指针 + +1. 因为 Python 的字符串是不可变的,所以我们先将字符串转为数组。 +2. 使用两个指针 $left$,$right$。$left$ 指向字符串开始位置,$right$ 指向字符串结束位置。 +3. 然后 $left$ 依次从左到右移动查找元音字母,$right$ 依次从右到左查找元音字母。 +4. 如果都找到了元音字母,则交换字符,然后继续进行查找。 +5. 如果遇到 $left == right$ 时停止。 +6. 最后返回对应的字符串即可。 -## 代码 +### 思路 1:代码 ```python class Solution: @@ -34,3 +64,7 @@ class Solution: return "".join(s_list) ``` +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$。其中 $n$ 为字符串 $s$ 的长度。 +- **空间复杂度**:$O(1)$。 \ No newline at end of file diff --git "a/Solutions/0374. \347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.md" "b/Solutions/0374. \347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.md" index 03ef1715..f2eb46ad 100644 --- "a/Solutions/0374. \347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.md" +++ "b/Solutions/0374. \347\214\234\346\225\260\345\255\227\345\244\247\345\260\217.md" @@ -5,9 +5,9 @@ ## 题目大意 -**描述**:猜数字游戏。给定一个整数 `n` 和一个接口 `def guess(num: int) -> int:`,题目会从 `1` ~ `n` 中随机选取一个数 `x`。我们只能通过调用接口来判断自己猜测的数是否正确。 +**描述**:猜数字游戏。给定一个整数 $n$ 和一个接口 `def guess(num: int) -> int:`,题目会从 $1 \sim n$ 中随机选取一个数 $x$。我们只能通过调用接口来判断自己猜测的数是否正确。 -**要求**:要求返回题目选取的数字 `x`。 +**要求**:要求返回题目选取的数字 $x$。 **说明**: @@ -25,14 +25,21 @@ 输出:6 ``` +- 示例 2: + +```python +输入:n = 1, pick = 1 +输出:1 +``` + ## 解题思路 ### 思路 1:二分查找 -利用两个指针 `left`、`right`。`left` 指向数字 `1`,`right` 指向数字 `n`。每次从中间开始调用接口猜测是否正确。 +利用两个指针 $left$、$right$。$left$ 指向数字 $1$,$right$ 指向数字 $n$。每次从中间开始调用接口猜测是否正确。 -- 如果猜测的数比选中的数大,则将 `right` 向左移,令 `right = mid - 1`,继续从中间调用接口猜测; -- 如果猜测的数比选中的数小,则将 `left` 向右移,令 `left = mid + 1`,继续从中间调用的接口猜测; +- 如果猜测的数比选中的数大,则将 $right$ 向左移,令 `right = mid - 1`,继续从中间调用接口猜测; +- 如果猜测的数比选中的数小,则将 $left$ 向右移,令 `left = mid + 1`,继续从中间调用的接口猜测; - 如果猜测正确,则直接返回该数。 ### 思路 1:二分查找代码 diff --git "a/Solutions/0485. \346\234\200\345\244\247\350\277\236\347\273\255 1 \347\232\204\344\270\252\346\225\260.md" "b/Solutions/0485. \346\234\200\345\244\247\350\277\236\347\273\255 1 \347\232\204\344\270\252\346\225\260.md" index 6ce9fb5e..d4423e93 100644 --- "a/Solutions/0485. \346\234\200\345\244\247\350\277\236\347\273\255 1 \347\232\204\344\270\252\346\225\260.md" +++ "b/Solutions/0485. \346\234\200\345\244\247\350\277\236\347\273\255 1 \347\232\204\344\270\252\346\225\260.md" @@ -5,25 +5,58 @@ ## 题目大意 -给定一个二进制数组,数组中只包含 0 和 1,计算其中最大连续 1 的个数。 +**描述**:给定一个二进制数组 $nums$, 数组中只包含 $0$ 和 $1$。 + +**要求**:计算其中最大连续 $1$ 的个数。 + +**说明**: + +- $1 \le nums.length \le 10^5$。 +- $nums[i]$ 不是 $0$ 就是 $1$。 + +**示例**: + +- 示例 1: + +```python +输入:nums = [1,1,0,1,1,1] +输出:3 +解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3. +``` + +- 示例 2: + +```python +输入:nums = [1,0,1,1,0,1] +输出:2 +``` ## 解题思路 -使用两个变量 sum 和 ans。sum 用于存储当前连续 1 的个数,ans 用于存储最大连续 1 的个数。然后进行一次遍历,统计当前连续 1 的个数,并更新最大的连续 1 个数。 +### 思路 1:一次遍历 -## 代码 +1. 使用两个变量 $cnt$ 和 $ans$。$cnt$ 用于存储当前连续 $1$ 的个数,$ans$ 用于存储最大连续 $1$ 的个数。 +2. 然后进行一次遍历,统计当前连续 $1$ 的个数,并更新最大的连续 $1$ 个数。 +3. 最后返回 $ans$ 作为答案。 + +### 思路 1:代码 ```python class Solution: def findMaxConsecutiveOnes(self, nums: List[int]) -> int: ans = 0 - sum = 0 + cnt = 0 for num in nums: if num == 1: - sum += 1 - ans = max(ans, sum) + cnt += 1 + ans = max(ans, cnt) else: - sum = 0 + cnt = 0 return ans ``` +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$。 +- **空间复杂度**:$O(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 d1cf20dd..ff842a2d 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" @@ -5,24 +5,49 @@ ## 题目大意 -给你一个由 `n` 个元素组成的整数数组 `nums` 和一个整数 `k`。 +**描述**:给定一个由 $n$ 个元素组成的整数数组 $nums$ 和一个整数 $k$。 -要求:找出平均数最大且长度为 `k` 的连续子数组,并输出该最大平均数。任何误差小于 $10^{-5}$ 的答案都将被视为正确答案。 +**要求**:找出平均数最大且长度为 $k$ 的连续子数组,并输出该最大平均数。 + +**说明**: + +- 任何误差小于 $10^{-5}$ 的答案都将被视为正确答案。 +- $n == nums.length$。 +- $1 \le k \le n \le 10^5$。 +- $-10^4 \le nums[i] \le 10^4$。 + +**示例**: + +- 示例 1: + +```python +输入:nums = [1,12,-5,-6,50,3], k = 4 +输出:12.75 +解释:最大平均数 (12-5-6+50)/4 = 51/4 = 12.75 +``` + +- 示例 2: + +```python +输入:nums = [5], k = 1 +输出:5.00000 +``` ## 解题思路 -这道题目是典型的固定窗口大小的滑动窗口题目。窗口大小为 `k`。具体做法如下: +### 思路 1:滑动窗口(固定长度) -1. `ans` 用来维护子数组最大平均数,初始值为负无穷,即 `float('-inf')`。`window_total` 用来维护窗口中元素的和。 -2. `left` 、`right` 都指向序列的第一个元素,即:`left = 0`,`right = 0`。 -3. 向右移动 `right`,先将 `k` 个元素填入窗口中。 -4. 当窗口元素个数为 `k` 时,即:`right - left + 1 >= k` 时,计算窗口内的元素和平均值,并维护子数组最大平均数。 -5. 然后向右移动 `left`,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 `k`。 -6. 重复 4 ~ 5 步,直到 `right` 到达数组末尾。 +这道题目是典型的固定窗口大小的滑动窗口题目。窗口大小为 $k$。具体做法如下: -最后输出答案 `ans`。 +1. $ans$ 用来维护子数组最大平均数,初始值为负无穷,即 `float('-inf')`。$window\underline{}total$ 用来维护窗口中元素的和。 +2. $left$ 、$right$ 都指向序列的第一个元素,即:`left = 0`,`right = 0`。 +3. 向右移动 $right$,先将 $k$ 个元素填入窗口中。 +4. 当窗口元素个数为 $k$ 时,即:$right - left + 1 >= k$ 时,计算窗口内的元素和平均值,并维护子数组最大平均数。 +5. 然后向右移动 $left$,从而缩小窗口长度,即 `left += 1`,使得窗口大小始终保持为 $k$。 +6. 重复 $4 \sim 5$ 步,直到 $right$ 到达数组末尾。 +7. 最后输出答案 $ans$。 -## 代码 +### 思路 1:代码 ```python class Solution: @@ -45,3 +70,7 @@ class Solution: return ans ``` +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n)$。其中 $n$ 为数组 $nums$ 的元素个数。 +- **空间复杂度**:$O(1)$。 \ No newline at end of file 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 3ce66df1..8f4a5e28 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" @@ -5,13 +5,13 @@ ## 题目大意 -**描述**:给定一个未经排序的数组 `nums`。 +**描述**:给定一个未经排序的数组 $nums$。 **要求**:找到最长且连续递增的子序列,并返回该序列的长度。 **说明**: -- **连续递增的子序列**:可以由两个下标 `l` 和 `r`(`l < r`)确定,如果对于每个 `l <= i < r`,都有 `nums[i] < nums[i + 1] `,那么子序列 `[nums[l], nums[l + 1], ..., nums[r - 1], nums[r]]` 就是连续递增子序列。 +- **连续递增的子序列**:可以由两个下标 $l$ 和 $r$($l < r$)确定,如果对于每个 $l \le i < r$,都有 $nums[i] < nums[i + 1] $,那么子序列 $[nums[l], nums[l + 1], ..., nums[r - 1], nums[r]]$ 就是连续递增子序列。 - $1 \le nums.length \le 10^4$。 - $-10^9 \le nums[i] \le 10^9$。 @@ -25,13 +25,21 @@ 解释:最长连续递增序列是 [1,3,5], 长度为 3。尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。 ``` +- 示例 2: + +```python +输入:nums = [2,2,2,2,2] +输出:1 +解释:最长连续递增序列是 [2], 长度为 1。 +``` + ## 解题思路 ### 思路 1:动态规划 ###### 1. 定义状态 -定义状态 `dp[i]` 表示为:以 `nums[i]` 结尾的最长且连续递增的子序列长度。 +定义状态 $dp[i]$ 表示为:以 $nums[i]$ 结尾的最长且连续递增的子序列长度。 ###### 2. 状态转移方程 @@ -39,21 +47,21 @@ 如果一个较小的数右侧相邻元素为一个较大的数,则会形成一个更长的递增子序列。 -对于相邻的数组元素 `nums[i - 1]` 和 `nums[i]` 来说: +对于相邻的数组元素 $nums[i - 1]$ 和 $nums[i]$ 来说: -- 如果 `nums[i - 1] < nums[i]`,则 `nums[i]` 可以接在 `nums[i - 1]` 后面,此时以 `nums[i]` 结尾的最长递增子序列长度会在「以 `nums[i - 1]` 结尾的最长递增子序列长度」的基础上加 `1`,即 `dp[i] = dp[i - 1] + 1`。 +- 如果 $nums[i - 1] < nums[i]$,则 $nums[i]$ 可以接在 $nums[i - 1]$ 后面,此时以 $nums[i]$ 结尾的最长递增子序列长度会在「以 $nums[i - 1]$ 结尾的最长递增子序列长度」的基础上加 $1$,即 $dp[i] = dp[i - 1] + 1$。 -- 如果 `nums[i - 1] >= nums[i]`,则 `nums[i]` 不可以接在 `nums[i - 1]` 后面,可以直接跳过。 +- 如果 $nums[i - 1] >= nums[i]$,则 $nums[i]$ 不可以接在 $nums[i - 1]$ 后面,可以直接跳过。 -综上,我们的状态转移方程为:`dp[i] = dp[i - 1] + 1`,`nums[i - 1] < nums[i]`。 +综上,我们的状态转移方程为:$dp[i] = dp[i - 1] + 1$,$nums[i - 1] < nums[i]$。 ###### 3. 初始条件 -默认状态下,把数组中的每个元素都作为长度为 `1` 的最长且连续递增的子序列长度。即 `dp[i] = 1`。 +默认状态下,把数组中的每个元素都作为长度为 $1$ 的最长且连续递增的子序列长度。即 $dp[i] = 1$。 ###### 4. 最终结果 -根据我们之前定义的状态,`dp[i]` 表示为:以 `nums[i]` 结尾的最长且连续递增的子序列长度。则为了计算出最大值,则需要再遍历一遍 `dp` 数组,求出最大值即为最终结果。 +根据我们之前定义的状态,$dp[i]$ 表示为:以 $nums[i]$ 结尾的最长且连续递增的子序列长度。则为了计算出最大值,则需要再遍历一遍 $dp$ 数组,求出最大值即为最终结果。 ### 思路 1:动态规划代码 @@ -77,14 +85,14 @@ class Solution: ### 思路 2:滑动窗口(不定长度) -1. 设定两个指针:`left`、`right`,分别指向滑动窗口的左右边界,保证窗口内为连续递增序列。使用 `window_len` 存储当前窗口大小,使用 `max_len` 维护最大窗口长度。 -2. 一开始,`left`、`right` 都指向 `0`。 -3. 将最右侧元素 `nums[right]` 加入当前连续递增序列中,即当前窗口长度加 `1`(`window_len += 1`)。 -4. 判断当前元素 `nums[right] `是否满足连续递增序列。 -5. 如果 `right > 0` 并且 `nums[right - 1] >= nums[right]` ,说明不满足连续递增序列,则将 `left` 移动到窗口最右侧,重置当前窗口长度为 `1`(`window_len = 1`)。 +1. 设定两个指针:$left$、$right$,分别指向滑动窗口的左右边界,保证窗口内为连续递增序列。使用 $window\underline{}len$ 存储当前窗口大小,使用 $max\underline{}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 >= len(nums)` 结束。 -8. 输出最长连续递增序列的长度 `max_len`。 +7. 继续右移 $right$,直到 $right \ge len(nums)$ 结束。 +8. 输出最长连续递增序列的长度 $max\underline{}len$。 ### 思路 2:代码 @@ -112,4 +120,4 @@ class Solution: ### 思路 2:复杂度分析 - **时间复杂度**:$O(n)$。 -- **空间复杂度**:$O(1)$。 +- **空间复杂度**:$O(1)$。 \ No newline at end of file diff --git "a/Solutions/0704. \344\272\214\345\210\206\346\237\245\346\211\276.md" "b/Solutions/0704. \344\272\214\345\210\206\346\237\245\346\211\276.md" index fece1559..12d13769 100644 --- "a/Solutions/0704. \344\272\214\345\210\206\346\237\245\346\211\276.md" +++ "b/Solutions/0704. \344\272\214\345\210\206\346\237\245\346\211\276.md" @@ -5,15 +5,15 @@ ## 题目大意 -**描述**:给定一个升序的数组 `nums`,和一个目标值 `target`。 +**描述**:给定一个升序的数组 $nums$,和一个目标值 $target$。 -**要求**:返回 `target` 在数组中的位置,如果找不到,则返回 -1。 +**要求**:返回 $target$ 在数组中的位置,如果找不到,则返回 -1。 **说明**: -- 你可以假设 `nums` 中的所有元素是不重复的。 -- `n` 将在 `[1, 10000]`之间。 -- `nums` 的每个元素都将在 `[-9999, 9999]`之间。 +- 你可以假设 $nums$ 中的所有元素是不重复的。 +- $n$ 将在 $[1, 10000]$之间。 +- $nums$ 的每个元素都将在 $[-9999, 9999]$之间。 **示例**: @@ -37,14 +37,13 @@ ### 思路 1:二分查找 -设定左右节点为数组两端,即 `left = 0`,`right = len(nums) - 1`,代表待查找区间为 `[left, right]`(左闭右闭)。 +设定左右节点为数组两端,即 `left = 0`,`right = len(nums) - 1`,代表待查找区间为 $[left, right]$(左闭右闭)。 -取两个节点中心位置 `mid`,先比较中心位置值 `nums[mid]` 与目标值 `target` 的大小。 - -- 如果中心位置值 `nums[mid]` 与目标值 `target` 相等,则返回中心位置。 -- 如果中心位置值 `nums[mid]` 小于目标值 `target`,则将左节点设置为 `mid + 1`,然后继续在右区间 `[mid + 1, right]` 搜索。 -- 如果中心位置值 `nums[mid]` 大于目标值 `target`,则将右节点设置为 `mid - 1`,然后继续在左区间 `[left, mid - 1]` 搜索。 +取两个节点中心位置 $mid$,先比较中心位置值 $nums[mid]$ 与目标值 $target$ 的大小。 +- 如果 $target == nums[mid]$,则返回中心位置。 +- 如果 $target > nums[mid]$,则将左节点设置为 $mid + 1$,然后继续在右区间 $[mid + 1, right]$ 搜索。 +- 如果中心位置值 $target < nums[mid]$,则将右节点设置为 $mid - 1$,然后继续在左区间 $[left, mid - 1]$ 搜索。 ### 思路 1:代码 @@ -72,6 +71,6 @@ class Solution: ### 思路 1:复杂度分析 -- **时间复杂度**:$O(\log_2n)$。 +- **时间复杂度**:$O(\log n)$。 - **空间复杂度**:$O(1)$。 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 f6e3f5d6..e7a65a90 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" @@ -5,25 +5,51 @@ ## 题目大意 -你的朋友正在使用键盘输入他的名字 `name`。偶尔,在键入字符时,按键可能会被长按,而字符可能被输入 `1` 次或多次。 +**描述**:你的朋友正在使用键盘输入他的名字 $name$。偶尔,在键入字符时,按键可能会被长按,而字符可能被输入 $1$ 次或多次。 -现在给定代表名字的字符串 `name`,以及实际输入的字符串 `typed`。 +现在给定代表名字的字符串 $name$,以及实际输入的字符串 $typed$。 -要求:检查键盘输入的字符 `typed`。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),就返回 `True`。否则返回 `False`。 +**要求**:检查键盘输入的字符 $typed$。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),就返回 `True`。否则返回 `False`。 + +**说明**: + +- $1 \le name.length, typed.length \le 1000$。 +- $name$ 和 $typed$ 的字符都是小写字母。 + +**示例**: + +- 示例 1: + +```python +输入:name = "alex", typed = "aaleex" +输出:true +解释:'alex' 中的 'a' 和 'e' 被长按。 +``` + +- 示例 2: + +```python +输入:name = "saeed", typed = "ssaaedd" +输出:false +解释:'e' 一定需要被键入两次,但在 typed 的输出中不是这样。 +``` ## 解题思路 -这道题目的意思是在 `typed` 里边匹配 `name`,同时要考虑字符重复问题,以及不匹配的情况。可以使用分离双指针来做。具体做法如下: +### 思路 1:分离双指针 + +这道题目的意思是在 $typed$ 里边匹配 $name$,同时要考虑字符重复问题,以及不匹配的情况。可以使用分离双指针来做。具体做法如下: -- 使用两个指针 `left_1`、`left_2`,`left_1` 指向字符串 `name` 开始位置,`left_2` 指向字符串 `type` 开始位置。 -- 如果 `name[left_1]` 等于 `name[left_2]`,则将 `left_1`、`left_2` 同时右移。 -- 如果 `nmae[left_1]` 不等于 `name[left_2]`,则: - - 如果 `typed[left_2]` 和前一个位置元素 `typed[left_2 - 1]` 相等,则说明出现了重复元素,将 `left_2` 右移,过滤重复元素。 - - 如果 `typed[left_2]` 和前一个位置元素 `typed[left_2 - 1]` 不等,则说明出现了多余元素,不匹配。直接返回 `False` 即可。 -- 当 `left_1 == len(name)` 或 `left_2 == len(typed)` 时跳出循环。然后过滤掉 `typed` 末尾的重复元素。 -- 最后判断,如果 `left_1 == len(name)` 并且 `left_2 == len(typed)`,则说明匹配,返回 `True`,否则返回 `False`。 +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:代码 ```python class Solution: @@ -47,3 +73,8 @@ class Solution: return False ``` +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n + m)$。其中 $n$、$m$ 分别为字符串 $name$、$typed$ 的长度。 +- **空间复杂度**:$O(1)$。 + 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 ae92637e..856c9979 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" @@ -5,14 +5,14 @@ ## 题目大意 -**描述**:给定一个由 `0`、`1` 组成的数组 `nums`,再给定一个整数 `k`。最多可以将 `k` 个值从 `0` 变到 `1`。 +**描述**:给定一个由 $0$、$1$ 组成的数组 $nums$,再给定一个整数 $k$。最多可以将 $k$ 个值从 $0$ 变到 $1$。 -**要求**:返回仅包含 `1` 的最长连续子数组的长度。 +**要求**:返回仅包含 $1$ 的最长连续子数组的长度。 **说明**: - $1 \le nums.length \le 10^5$。 -- `nums[i]` 不是 `0` 就是 `1`。 +- $nums[i]$ 不是 $0$ 就是 $1$。 - $0 \le k \le nums.length$。 **示例**: @@ -24,8 +24,11 @@ 输出:6 解释:[1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1] 将 nums[5]、nums[10] 从 0 翻转到 1,最长的子数组长度为 6。 +``` +- 示例 2: +```python 输入:nums = [0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1], K = 3 输出:10 解释:[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1] @@ -36,10 +39,10 @@ ### 思路 1:滑动窗口(不定长度) -1. 使用两个指针 `left`、`right` 指向数组开始位置。使用 `max_count` 来维护仅包含 `1` 的最长连续子数组的长度。 -2. 不断右移 `right` 指针,扩大滑动窗口范围,并统计窗口内 `0` 元素的个数。 -3. 直到 `0` 元素的个数超过 `k` 时将 `left` 右移,缩小滑动窗口范围,并减小 `0` 元素的个数,同时维护 `max_count`。 -4. 最后输出最长连续子数组的长度 `max_count`。 +1. 使用两个指针 $left$、$right$ 指向数组开始位置。使用 $max\underline{}count$ 来维护仅包含 $1$ 的最长连续子数组的长度。 +2. 不断右移 $right$ 指针,扩大滑动窗口范围,并统计窗口内 $0$ 元素的个数。 +3. 直到 $0$ 元素的个数超过 $k$ 时将 $left$ 右移,缩小滑动窗口范围,并减小 $0$ 元素的个数,同时维护 $max\underline{}count$。 +4. 最后输出最长连续子数组的长度 $max\underline{}count$。 ### 思路 1:代码 diff --git "a/Solutions/1011. \345\234\250 D \345\244\251\345\206\205\351\200\201\350\276\276\345\214\205\350\243\271\347\232\204\350\203\275\345\212\233.md" "b/Solutions/1011. \345\234\250 D \345\244\251\345\206\205\351\200\201\350\276\276\345\214\205\350\243\271\347\232\204\350\203\275\345\212\233.md" index f04d7854..448a73c7 100644 --- "a/Solutions/1011. \345\234\250 D \345\244\251\345\206\205\351\200\201\350\276\276\345\214\205\350\243\271\347\232\204\350\203\275\345\212\233.md" +++ "b/Solutions/1011. \345\234\250 D \345\244\251\345\206\205\351\200\201\350\276\276\345\214\205\350\243\271\347\232\204\350\203\275\345\212\233.md" @@ -5,9 +5,9 @@ ## 题目大意 -**描述**:传送带上的包裹必须在 `D` 天内从一个港口运送到另一个港口。给定所有包裹的重量数组 `weights`,货物必须按照给定的顺序装运。且每天船上装载的重量不会超过船的最大运载重量。 +**描述**:传送带上的包裹必须在 $D$ 天内从一个港口运送到另一个港口。给定所有包裹的重量数组 $weights$,货物必须按照给定的顺序装运。且每天船上装载的重量不会超过船的最大运载重量。 -**要求**:求能在 `D` 天内将所有包裹送达的船的最低运载量。 +**要求**:求能在 $D$ 天内将所有包裹送达的船的最低运载量。 **说明**: @@ -47,9 +47,9 @@ ### 思路 1:二分查找 -船最小的运载能力,最少也要等于或大于最重的那件包裹,即 `max(weights)`。最多的话,可以一次性将所有包裹运完,即 `sum(weights)`。船的运载能力介于 `[max(weights), sum(weights)]` 之间。 +船最小的运载能力,最少也要等于或大于最重的那件包裹,即 $max(weights)$。最多的话,可以一次性将所有包裹运完,即 $sum(weights)$。船的运载能力介于 $[max(weights), sum(weights)]$ 之间。 -我们现在要做的就是从这个区间内,找到满足可以在 `D` 天内运送完所有包裹的最小载重量。 +我们现在要做的就是从这个区间内,找到满足可以在 $D$ 天内运送完所有包裹的最小载重量。 可以通过二分查找的方式,找到满足要求的最小载重量。 @@ -80,6 +80,6 @@ class Solution: ### 思路 1:复杂度分析 -- **时间复杂度**:$O(\log_2 n)$。二分查找算法的时间复杂度为 $O(\log_2 n)$。 +- **时间复杂度**:$O(\log n)$。二分查找算法的时间复杂度为 $O(\log n)$。 - **空间复杂度**:$O(1)$。只用到了常数空间存放若干变量。