-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
268 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)$。 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)$。 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |)$。 |