Skip to content

Commit 61d4e99

Browse files
committed
feat: update solutions to lc problem: no.3003
1 parent cf8d64c commit 61d4e99

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

solution/3000-3099/3003.Maximize the Number of Partitions After Operations/README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,19 @@ tags:
100100

101101
<!-- solution:start -->
102102

103-
### 方法一
103+
### 方法一:记忆化搜索
104+
105+
我们设计一个函数 $\texti{dfs}(i, \textit{cur}, t)$ 表示当前处理到字符串 $s$ 的下标 $i$,当前前缀中已经包含的字符集合为 $\textit{cur}$,并且还可以修改 $t$ 次字符时,能够得到的最大分割数量。那么答案即为 $\textit{dfs}(0, 0, 1)$。
106+
107+
函数 $\textit{dfs}(i, \textit{cur}, t)$ 的执行逻辑如下:
108+
109+
1. 如果 $i \geq n$,说明已经处理完字符串 $s$,返回 1。
110+
2. 计算当前字符 $s[i]$ 对应的位掩码 $v = 1 \ll (s[i] - 'a')$,并计算更新后的字符集合 $\textit{nxt} = \textit{cur} \mid v$。
111+
3. 如果 $\textit{nxt}$ 中的位数超过 $k$,说明当前前缀已经包含超过 $k$ 个不同字符,我们需要进行一次分割,此时分割数量加 1,并递归调用 $\textit{dfs}(i + 1, v, t)$;否则,继续递归调用 $\textit{dfs}(i + 1, \textit{nxt}, t)$。
112+
4. 如果 $t > 0$,说明我们还可以修改一次字符。我们尝试将当前字符 $s[i]$ 修改为任意一个小写字母(共 26 种选择),对于每个选择,计算更新后的字符集合 $\textit{nxt} = \textit{cur} \mid (1 \ll j)$,并根据是否超过 $k$ 个不同字符,选择相应的递归调用方式,更新最大分割数量。
113+
5. 使用哈希表缓存已经计算过的状态,避免重复计算。
114+
115+
时间复杂度 $O(n \times |\Sigma| \times k)$,空间复杂度 $O(n \times |\Sigma| \times k)$。其中 $n$ 为字符串 $s$ 的长度,而 $|\Sigma|$ 为字符集大小。
104116

105117
<!-- tabs:start -->
106118

@@ -181,7 +193,7 @@ public:
181193
int maxPartitionsAfterOperations(string s, int k) {
182194
int n = s.size();
183195
unordered_map<long long, int> f;
184-
function<int(int, int, int)> dfs = [&](int i, int cur, int t) {
196+
auto dfs = [&](this auto&& dfs, int i, int cur, int t) -> int {
185197
if (i >= n) {
186198
return 1;
187199
}

solution/3000-3099/3003.Maximize the Number of Partitions After Operations/README_EN.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,19 @@ tags:
9898

9999
<!-- solution:start -->
100100

101-
### Solution 1
101+
### Solution 1: Memoized Search
102+
103+
We design a function $\textit{dfs}(i, \textit{cur}, t)$ that represents the maximum number of partitions we can obtain when currently processing index $i$ of string $s$, the current prefix already contains the character set $\textit{cur}$, and we can still modify $t$ characters. Then the answer is $\textit{dfs}(0, 0, 1)$.
104+
105+
The execution logic of function $\textit{dfs}(i, \textit{cur}, t)$ is as follows:
106+
107+
1. If $i \geq n$, it means we have finished processing string $s$, return 1.
108+
2. Calculate the bitmask $v = 1 \ll (s[i] - 'a')$ corresponding to the current character $s[i]$, and calculate the updated character set $\textit{nxt} = \textit{cur} \mid v$.
109+
3. If the number of bits in $\textit{nxt}$ exceeds $k$, it means the current prefix already contains more than $k$ distinct characters. We need to make a partition, increment the partition count by 1, and recursively call $\textit{dfs}(i + 1, v, t)$. Otherwise, continue recursively calling $\textit{dfs}(i + 1, \textit{nxt}, t)$.
110+
4. If $t > 0$, it means we can still modify a character once. We try to change the current character $s[i]$ to any lowercase letter (26 choices in total). For each choice, calculate the updated character set $\textit{nxt} = \textit{cur} \mid (1 \ll j)$, and based on whether it exceeds $k$ distinct characters, choose the corresponding recursive call method to update the maximum partition count.
111+
5. Use a hash table to cache already computed states to avoid redundant calculations.
112+
113+
The time complexity is $O(n \times |\Sigma| \times k)$ and the space complexity is $O(n \times |\Sigma| \times k)$, where $n$ is the length of string $s$, and $|\Sigma|$ is the size of the character set.
102114

103115
<!-- tabs:start -->
104116

@@ -179,7 +191,7 @@ public:
179191
int maxPartitionsAfterOperations(string s, int k) {
180192
int n = s.size();
181193
unordered_map<long long, int> f;
182-
function<int(int, int, int)> dfs = [&](int i, int cur, int t) {
194+
auto dfs = [&](this auto&& dfs, int i, int cur, int t) -> int {
183195
if (i >= n) {
184196
return 1;
185197
}

solution/3000-3099/3003.Maximize the Number of Partitions After Operations/Solution.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class Solution {
33
int maxPartitionsAfterOperations(string s, int k) {
44
int n = s.size();
55
unordered_map<long long, int> f;
6-
function<int(int, int, int)> dfs = [&](int i, int cur, int t) {
6+
auto dfs = [&](this auto&& dfs, int i, int cur, int t) -> int {
77
if (i >= n) {
88
return 1;
99
}
@@ -28,4 +28,4 @@ class Solution {
2828
};
2929
return dfs(0, 0, 1);
3030
}
31-
};
31+
};

0 commit comments

Comments
 (0)