diff --git a/Contents/00.Introduction/04.Solutions-List.md b/Contents/00.Introduction/04.Solutions-List.md index e787248c..6e4fa944 100644 --- a/Contents/00.Introduction/04.Solutions-List.md +++ b/Contents/00.Introduction/04.Solutions-List.md @@ -1,4 +1,4 @@ -# LeetCode 题解(已完成 844 道) +# LeetCode 题解(已完成 847 道) | 题号 | 标题 | 题解 | 标签 | 难度 | | :------ | :------ | :------ | :------ | :------ | @@ -461,6 +461,7 @@ | 0887 | [鸡蛋掉落](https://leetcode.cn/problems/super-egg-drop/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0887.%20%E9%B8%A1%E8%9B%8B%E6%8E%89%E8%90%BD.md) | 数学、二分查找、动态规划 | 困难 | | 0889 | [根据前序和后序遍历构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-postorder-traversal/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0889.%20%E6%A0%B9%E6%8D%AE%E5%89%8D%E5%BA%8F%E5%92%8C%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91.md) | 树、数组、哈希表、分治、二叉树 | 中等 | | 0897 | [递增顺序搜索树](https://leetcode.cn/problems/increasing-order-search-tree/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0897.%20%E9%80%92%E5%A2%9E%E9%A1%BA%E5%BA%8F%E6%90%9C%E7%B4%A2%E6%A0%91.md) | 栈、树、深度优先搜索、二叉搜索树、二叉树 | 简单 | +| 0900 | [RLE 迭代器](https://leetcode.cn/problems/rle-iterator/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0900.%20RLE%20%E8%BF%AD%E4%BB%A3%E5%99%A8.md) | 设计、数组、计数、迭代器 | 中等 | | 0901 | [股票价格跨度](https://leetcode.cn/problems/online-stock-span/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0901.%20%E8%82%A1%E7%A5%A8%E4%BB%B7%E6%A0%BC%E8%B7%A8%E5%BA%A6.md) | 栈、设计、数据流、单调栈 | 中等 | | 0902 | [最大为 N 的数字组合](https://leetcode.cn/problems/numbers-at-most-n-given-digit-set/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0902.%20%E6%9C%80%E5%A4%A7%E4%B8%BA%20N%20%E7%9A%84%E6%95%B0%E5%AD%97%E7%BB%84%E5%90%88.md) | 数组、数学、字符串、二分查找、动态规划 | 困难 | | 0904 | [水果成篮](https://leetcode.cn/problems/fruit-into-baskets/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/0904.%20%E6%B0%B4%E6%9E%9C%E6%88%90%E7%AF%AE.md) | 数组、哈希表、滑动窗口 | 中等 | @@ -562,6 +563,7 @@ | 1347 | [制造字母异位词的最小步骤数](https://leetcode.cn/problems/minimum-number-of-steps-to-make-two-strings-anagram/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1347.%20%E5%88%B6%E9%80%A0%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D%E7%9A%84%E6%9C%80%E5%B0%8F%E6%AD%A5%E9%AA%A4%E6%95%B0.md) | 哈希表、字符串、计数 | 中等 | | 1349 | [参加考试的最大学生数](https://leetcode.cn/problems/maximum-students-taking-exam/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1349.%20%E5%8F%82%E5%8A%A0%E8%80%83%E8%AF%95%E7%9A%84%E6%9C%80%E5%A4%A7%E5%AD%A6%E7%94%9F%E6%95%B0.md) | 位运算、数组、动态规划、状态压缩、矩阵 | 困难 | | 1358 | [包含所有三种字符的子字符串数目](https://leetcode.cn/problems/number-of-substrings-containing-all-three-characters/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1358.%20%E5%8C%85%E5%90%AB%E6%89%80%E6%9C%89%E4%B8%89%E7%A7%8D%E5%AD%97%E7%AC%A6%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%9B%AE.md) | 哈希表、字符串、滑动窗口 | 中等 | +| 1362 | [最接近的因数](https://leetcode.cn/problems/closest-divisors/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1362.%20%E6%9C%80%E6%8E%A5%E8%BF%91%E7%9A%84%E5%9B%A0%E6%95%B0.md) | 数学 | 中等 | | 1381 | [设计一个支持增量操作的栈](https://leetcode.cn/problems/design-a-stack-with-increment-operation/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1381.%20%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81%E5%A2%9E%E9%87%8F%E6%93%8D%E4%BD%9C%E7%9A%84%E6%A0%88.md) | 栈、设计、数组 | 中等 | | 1400 | [构造 K 个回文字符串](https://leetcode.cn/problems/construct-k-palindrome-strings/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1400.%20%E6%9E%84%E9%80%A0%20K%20%E4%B8%AA%E5%9B%9E%E6%96%87%E5%AD%97%E7%AC%A6%E4%B8%B2.md) | 贪心、哈希表、字符串、计数 | 中等 | | 1408 | [数组中的字符串匹配](https://leetcode.cn/problems/string-matching-in-an-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1408.%20%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8C%B9%E9%85%8D.md) | 数组、字符串、字符串匹配 | 简单 | @@ -625,6 +627,7 @@ | 1903 | [字符串中的最大奇数](https://leetcode.cn/problems/largest-odd-number-in-string/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1903.%20%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E6%9C%80%E5%A4%A7%E5%A5%87%E6%95%B0.md) | 贪心、数学、字符串 | 简单 | | 1925 | [统计平方和三元组的数目](https://leetcode.cn/problems/count-square-sum-triples/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1925.%20%E7%BB%9F%E8%AE%A1%E5%B9%B3%E6%96%B9%E5%92%8C%E4%B8%89%E5%85%83%E7%BB%84%E7%9A%84%E6%95%B0%E7%9B%AE.md) | 数学、枚举 | 简单 | | 1929 | [数组串联](https://leetcode.cn/problems/concatenation-of-array/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1929.%20%E6%95%B0%E7%BB%84%E4%B8%B2%E8%81%94.md) | 数组 | 简单 | +| 1930 | [长度为 3 的不同回文子序列](https://leetcode.cn/problems/unique-length-3-palindromic-subsequences/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1930.%20%E9%95%BF%E5%BA%A6%E4%B8%BA%203%20%E7%9A%84%E4%B8%8D%E5%90%8C%E5%9B%9E%E6%96%87%E5%AD%90%E5%BA%8F%E5%88%97.md) | 哈希表、字符串、前缀和 | 中等 | | 1936 | [新增的最少台阶数](https://leetcode.cn/problems/add-minimum-number-of-rungs/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1936.%20%E6%96%B0%E5%A2%9E%E7%9A%84%E6%9C%80%E5%B0%91%E5%8F%B0%E9%98%B6%E6%95%B0.md) | 贪心、数组 | 中等 | | 1941 | [检查是否所有字符出现次数相同](https://leetcode.cn/problems/check-if-all-characters-have-equal-number-of-occurrences/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1941.%20%E6%A3%80%E6%9F%A5%E6%98%AF%E5%90%A6%E6%89%80%E6%9C%89%E5%AD%97%E7%AC%A6%E5%87%BA%E7%8E%B0%E6%AC%A1%E6%95%B0%E7%9B%B8%E5%90%8C.md) | 哈希表、字符串、计数 | 简单 | | 1947 | [最大兼容性评分和](https://leetcode.cn/problems/maximum-compatibility-score-sum/) | [Python](https://github.com/itcharge/LeetCode-Py/blob/main/Solutions/1947.%20%E6%9C%80%E5%A4%A7%E5%85%BC%E5%AE%B9%E6%80%A7%E8%AF%84%E5%88%86%E5%92%8C.md) | 位运算、数组、动态规划、回溯、状态压缩 | 中等 | diff --git a/README.md b/README.md index 1fa7bbc3..25322b95 100644 --- a/README.md +++ b/README.md @@ -255,4 +255,4 @@ - [动态规划优化题目](./Contents/10.Dynamic-Programming/11.DP-Optimization/04.DP-Optimization-List.md) ## 11. 附加内容 -## [12. LeetCode 题解(已完成 844 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file +## [12. LeetCode 题解(已完成 847 道)](./Contents/00.Introduction/04.Solutions-List.md) \ No newline at end of file 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" new file mode 100644 index 00000000..d806bc71 --- /dev/null +++ "b/Solutions/0900. RLE \350\277\255\344\273\243\345\231\250.md" @@ -0,0 +1,92 @@ +# [0900. RLE 迭代器](https://leetcode.cn/problems/rle-iterator/) + +- 标签:设计、数组、计数、迭代器 +- 难度:中等 + +## 题目链接 + +- [0900. RLE 迭代器 - 力扣](https://leetcode.cn/problems/rle-iterator/) + +## 题目大意 + +**描述**:我们可以使用游程编码(即 RLE)来编码一个整数序列。在偶数长度 $encoding$ ( 从 $0$ 开始 )的游程编码数组中,对于所有偶数 $i$,$encoding[i]$ 告诉我们非负整数 $encoding[i + 1]$ 在序列中重复的次数。 + +- 例如,序列 $arr = [8,8,8,5,5]$ 可以被编码为 $encoding =[3,8,2,5]$。$encoding =[3,8,0,9,2,5]$ 和 $encoding =[2,8,1,8,2,5]$ 也是 $arr$ 有效的 RLE。 + +给定一个游程长度的编码数组 $encoding$。 + +**要求**:设计一个迭代器来遍历它。 + +实现 `RLEIterator` 类: + +- `RLEIterator(int[] encoded)` 用编码后的数组初始化对象。 +- `int next(int n)` 以这种方式耗尽后 $n$ 个元素并返回最后一个耗尽的元素。如果没有剩余的元素要耗尽,则返回 $-1$。 + +**说明**: + +- $2 \le encoding.length \le 1000$。 +- $encoding.length$ 为偶。 +- $0 \le encoding[i] \le 10^9$。 +- $1 \le n \le 10^9$。 +- 每个测试用例调用 `next` 不高于 $1000$ 次。 + +**示例**: + +- 示例 1: + +```python +输入: +["RLEIterator","next","next","next","next"] +[[[3,8,0,9,2,5]],[2],[1],[1],[2]] +输出: +[null,8,8,5,-1] +解释: +RLEIterator rLEIterator = new RLEIterator([3, 8, 0, 9, 2, 5]); // 这映射到序列 [8,8,8,5,5]。 +rLEIterator.next(2); // 耗去序列的 2 个项,返回 8。现在剩下的序列是 [8, 5, 5]。 +rLEIterator.next(1); // 耗去序列的 1 个项,返回 8。现在剩下的序列是 [5, 5]。 +rLEIterator.next(1); // 耗去序列的 1 个项,返回 5。现在剩下的序列是 [5]。 +rLEIterator.next(2); // 耗去序列的 2 个项,返回 -1。 这是由于第一个被耗去的项是 5, +但第二个项并不存在。由于最后一个要耗去的项不存在,我们返回 -1。 +``` + +## 解题思路 + +### 思路 1:模拟 + +1. 初始化时: + 1. 保存数组 $encoding$ 作为成员变量。 + 2. 保存当前位置 $index$,表示当前迭代器指向元素 $encoding[index + 1]$。初始化赋值为 $0$。 + 3. 保存当前指向元素 $encoding[index + 1]$ 已经被删除的元素个数 $d\underline{}cnt$。初始化赋值为 $0$。 +2. 调用 `next(n)` 时: + 1. 对于当前元素,先判断当前位置是否超出 $encoding$ 范围,超过则直接返回 $-1$。 + 2. 如果未超过,再判断当前元素剩余个数 $encoding[index] - d\underline{}cnt$ 是否小于 $n$ 个。 + 1. 如果小于 $n$ 个,则删除当前元素剩余所有个数,并指向下一位置继续删除剩余元素。 + 2. 如果等于大于等于 $n$ 个,则令当前指向元素 $encoding[index + 1]$ 已经被删除的元素个数 $d\underline{}cnt$ 加上 $n$。 + +### 思路 1:代码 + +```Python +class RLEIterator: + + def __init__(self, encoding: List[int]): + self.encoding = encoding + self.index = 0 + self.d_cnt = 0 + + def next(self, n: int) -> int: + while self.index < len(self.encoding): + if self.d_cnt + n > self.encoding[self.index]: + n -= self.encoding[self.index] - self.d_cnt + self.d_cnt = 0 + self.index += 2 + else: + self.d_cnt += n + return self.encoding[self.index + 1] + return -1 +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$O(n + m)$,其中 $n$ 为数组 $encoding$ 的长度,$m$ 是调用 `next(n)` 的次数。 +- **空间复杂度**:$O(n)$。 + diff --git "a/Solutions/1362. \346\234\200\346\216\245\350\277\221\347\232\204\345\233\240\346\225\260.md" "b/Solutions/1362. \346\234\200\346\216\245\350\277\221\347\232\204\345\233\240\346\225\260.md" new file mode 100644 index 00000000..9ccf4b17 --- /dev/null +++ "b/Solutions/1362. \346\234\200\346\216\245\350\277\221\347\232\204\345\233\240\346\225\260.md" @@ -0,0 +1,76 @@ +# [1362. 最接近的因数](https://leetcode.cn/problems/closest-divisors/) + +- 标签:数学 +- 难度:中等 + +## 题目链接 + +- [1362. 最接近的因数 - 力扣](https://leetcode.cn/problems/closest-divisors/) + +## 题目大意 + +**描述**:给定一个整数 $num$。 + +**要求**:找出同时满足下面全部要求的两个整数: + +- 两数乘积等于 $num + 1$ 或 $num + 2$。 +- 以绝对差进行度量,两数大小最接近。 + +你可以按照任意顺序返回这两个整数。 + +**说明**: + +- $1 \le num \le 10^9$。 + +**示例**: + +- 示例 1: + +```python +输入:num = 8 +输出:[3,3] +解释:对于 num + 1 = 9,最接近的两个因数是 3 & 3;对于 num + 2 = 10, 最接近的两个因数是 2 & 5,因此返回 3 & 3。 +``` + +- 示例 2: + +```python +输入:num = 123 +输出:[5,25] +``` + +## 解题思路 + +### 思路 1:数学 + +对于整数的任意一个范围在 $[\sqrt{n}, n]$ 的因数而言,一定存在一个范围在 $[1, \sqrt{n}]$ 的因数与其对应。因此,我们在遍历整数因数时,我们只需遍历 $[1, \sqrt{n}]$ 范围内的因数即可。 + +则这道题的具体解题步骤如下: + +1. 对于整数 $num + 1$、从 $\sqrt{num + 1}$ 的位置开始,到 $1$ 为止,以递减的顺序在 $[1, \sqrt{num + 1}]$ 范围内找到最接近的小因数 $a1$,并根据 $num // a1$ 获得另一个因数 $a2$。 +2. 用同样的方式,对于整数 $num + 2$、从 $\sqrt{num + 2}$ 的位置开始,到 $1$ 为止,以递减的顺序在 $[1, \sqrt{num + 2}]$ 范围内找到最接近的小因数 $b1$,并根据 $num // b1$ 获得另一个因数 $b2$。 +3. 判断 $abs(a1 - a2)$ 与 $abs(b1 - b2)$ 的大小,返回差值绝对值较小的一对因子数作为答案。 + +### 思路 1:代码 + +```Python +class Solution: + def disassemble(self, num): + for i in range(int(sqrt(num) + 1), 1, -1): + if num % i == 0: + return (i, num // i) + return (1, num) + + def closestDivisors(self, num: int) -> List[int]: + a1, a2 = self.disassemble(num + 1) + b1, b2 = self.disassemble(num + 2) + if abs(a1 - a2) <= abs(b1 - b2): + return [a1, a2] + return [b1, b2] +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$(\sqrt{n})$。 +- **空间复杂度**:$O(1)$。 + diff --git "a/Solutions/1930. \351\225\277\345\272\246\344\270\272 3 \347\232\204\344\270\215\345\220\214\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.md" "b/Solutions/1930. \351\225\277\345\272\246\344\270\272 3 \347\232\204\344\270\215\345\220\214\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.md" new file mode 100644 index 00000000..f02dd0fc --- /dev/null +++ "b/Solutions/1930. \351\225\277\345\272\246\344\270\272 3 \347\232\204\344\270\215\345\220\214\345\233\236\346\226\207\345\255\220\345\272\217\345\210\227.md" @@ -0,0 +1,95 @@ +# [1930. 长度为 3 的不同回文子序列](https://leetcode.cn/problems/unique-length-3-palindromic-subsequences/) + +- 标签:哈希表、字符串、前缀和 +- 难度:中等 + +## 题目链接 + +- [1930. 长度为 3 的不同回文子序列 - 力扣](https://leetcode.cn/problems/unique-length-3-palindromic-subsequences/) + +## 题目大意 + +**描述**:给定一个人字符串 $s$。 + +**要求**:返回 $s$ 中长度为 $s$ 的不同回文子序列的个数。即便存在多种方法来构建相同的子序列,但相同的子序列只计数一次。 + +**说明**: + +- **回文**:指正着读和反着读一样的字符串。 +- **子序列**:由原字符串删除其中部分字符(也可以不删除)且不改变剩余字符之间相对顺序形成的一个新字符串。 + - 例如,`"ace"` 是 `"abcde"` 的一个子序列。 + +- $3 \le s.length \le 10^5$。 +- $s$ 仅由小写英文字母组成。 + +**示例**: + +- 示例 1: + +```python +输入:s = "aabca" +输出:3 +解释:长度为 3 的 3 个回文子序列分别是: +- "aba" ("aabca" 的子序列) +- "aaa" ("aabca" 的子序列) +- "aca" ("aabca" 的子序列) +``` + +- 示例 2: + +```python +输入:s = "bbcbaba" +输出:4 +解释:长度为 3 的 4 个回文子序列分别是: +- "bbb" ("bbcbaba" 的子序列) +- "bcb" ("bbcbaba" 的子序列) +- "bab" ("bbcbaba" 的子序列) +- "aba" ("bbcbaba" 的子序列) +``` + +## 解题思路 + +### 思路 1:枚举 + 哈希表 + +字符集只包含 $26$ 个小写字母,所以我们可以枚举这 $26$ 个小写字母。 + +对于每个小写字母,使用对撞双指针,找到字符串 $s$ 首尾两侧与小写字母相同的最左位置和最右位置。 + +如果两个位置不同,则我们可以将两个位置中间不重复的字符当作是长度为 $3$ 的子序列最中间的那个字符。 + +则我们可以统计出两个位置中间不重复字符的个数,将其累加到答案中。 + +遍历完,返回答案。 + +### 思路 1:代码 + +```Python +class Solution: + def countPalindromicSubsequence(self, s: str) -> int: + size = len(s) + ans = 0 + + for i in range(26): + left, right = 0, size - 1 + + while left < size and ord(s[left]) - ord('a') != i: + left += 1 + + while right >= 0 and ord(s[right]) - ord('a') != i: + right -= 1 + + if right - left < 2: + continue + + char_set = set() + for j in range(left + 1, right): + char_set.add(s[j]) + ans += len(char_set) + + return ans +``` + +### 思路 1:复杂度分析 + +- **时间复杂度**:$n \times | \sum | + | \sum |^2$,其中 $n$ 为字符串 $s$ 的长度,$\sum$ 为字符集,本题中 $| \sum | = 26$。 +- **空间复杂度**:$O(| \sum |)$。