Skip to content

Commit ceefab4

Browse files
committed
feat: add solutions to lc problem: No.1653
No.1653.Minimum Deletions to Make String Balanced
1 parent 8fabb29 commit ceefab4

File tree

6 files changed

+228
-67
lines changed

6 files changed

+228
-67
lines changed

solution/1600-1699/1653.Minimum Deletions to Make String Balanced/README.md

Lines changed: 122 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,35 @@
4747

4848
**方法一:动态规划**
4949

50-
定义 `dp[i]` 表示字符串 `s[0..i)` 达到平衡时,需要删除的最少字符数,答案为 `dp[n]`。用变量 $b$ 统计字符 `b` 的个数
50+
我们定义 $f[i]$ 表示前 $i$ 个字符中,删除最少的字符数,使得字符串平衡。初始时 $f[0]=0$。答案为 $f[n]$
5151

52-
遍历字符串 $s$
52+
我们遍历字符串 $s$,维护变量 $b$,表示当前遍历到的位置之前的字符中,字符 $b$ 的个数。
5353

54-
如果当前字符为 `b`,此时不影响平衡串的最小删除次数,那么 $dp[i]=dp[i-1]$,并且累加 $b$。
54+
- 如果当前字符为 `'b'`,此时不影响前 $i$ 个字符的平衡性,因此 $f[i]=f[i-1]$,然后我们更新 $b \leftarrow b+1$。
55+
- 如果当前字符为 `'a'`,此时我们可以选择删除当前字符,那么有 $f[i]=f[i-1]+1$;也可以选择删除之前的字符 $b$,那么有 $f[i]=b$。因此我们取两者的最小值,即 $f[i]=\min(f[i-1]+1,b)$。
5556

56-
如果当前字符为 `a`,此时,要想达到平衡,要么把前面的所有 `b` 都删掉,操作次数为 $b$;要么把当前的 `a` 删除,操作次数为 $dp[i-1]+1$。取两者的最小值即可。即 $dp[i]=\min(b,dp[i-1]+1)$。
57+
综上,我们可以得到状态转移方程:
5758

58-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $s$ 的长度。
59+
$$
60+
f[i]=\begin{cases}
61+
f[i-1], & s[i-1]='b'\\
62+
\min(f[i-1]+1,b), & s[i-1]='a'
63+
\end{cases}
64+
$$
5965

60-
我们发现 $dp[i]$ 只与 $dp[i-1]$ 有关,因此可以使用变量 `ans` 来代替数组 `dp`。空间复杂度优化为 $O(1)$。
66+
最终答案为 $f[n]$。
67+
68+
我们注意到,状态转移方程中只与前一个状态以及变量 $b$ 有关,因此我们可以仅用一个答案变量 $ans$ 维护当前的 $f[i]$,并不需要开辟数组 $f$。
69+
70+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
71+
72+
**方法二:枚举 + 前缀和**
73+
74+
我们可以枚举字符串 $s$ 中的每一个位置 $i$,将字符串 $s$ 分成两部分,分别为 $s[0,..,i-1]$ 和 $s[i+1,..n-1]$,要使得字符串平衡,我们在当前位置 $i$ 需要删除的字符数为 $s[0,..,i-1]$ 中字符 $b$ 的个数加上 $s[i+1,..n-1]$ 中字符 $a$ 的个数。
75+
76+
因此,我们维护两个变量 $lb$ 和 $ra$ 分别表示 $s[0,..,i-1]$ 中字符 $b$ 的个数以及 $s[i+1,..n-1]$ 中字符 $a$ 的个数,那么我们需要删除的字符数为 $lb+ra$。枚举过程中,更新变量 $lb$ 和 $ra$。
77+
78+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为字符串 $s$ 的长度。
6179

6280
<!-- tabs:start -->
6381

@@ -69,15 +87,15 @@
6987
class Solution:
7088
def minimumDeletions(self, s: str) -> int:
7189
n = len(s)
72-
dp = [0] * (n + 1)
90+
f = [0] * (n + 1)
7391
b = 0
7492
for i, c in enumerate(s, 1):
7593
if c == 'b':
76-
dp[i] = dp[i - 1]
94+
f[i] = f[i - 1]
7795
b += 1
7896
else:
79-
dp[i] = min(dp[i - 1] + 1, b)
80-
return dp[n]
97+
f[i] = min(f[i - 1] + 1, b)
98+
return f[n]
8199
```
82100

83101
```python
@@ -88,7 +106,19 @@ class Solution:
88106
if c == 'b':
89107
b += 1
90108
else:
91-
ans = min(b, ans + 1)
109+
ans = min(ans + 1, b)
110+
return ans
111+
```
112+
113+
```python
114+
class Solution:
115+
def minimumDeletions(self, s: str) -> int:
116+
lb, ra = 0, s.count('a')
117+
ans = len(s)
118+
for c in s:
119+
ra -= c == 'a'
120+
ans = min(ans, lb + ra)
121+
lb += c == 'b'
92122
return ans
93123
```
94124

@@ -100,32 +130,54 @@ class Solution:
100130
class Solution {
101131
public int minimumDeletions(String s) {
102132
int n = s.length();
103-
int[] dp = new int[n + 1];
133+
int[] f = new int[n + 1];
104134
int b = 0;
105-
for (int i = 0; i < n; ++i) {
106-
if (s.charAt(i) == 'b') {
107-
dp[i + 1] = dp[i];
135+
for (int i = 1; i <= n; ++i) {
136+
if (s.charAt(i - 1) == 'b') {
137+
f[i] = f[i - 1];
108138
++b;
109139
} else {
110-
dp[i + 1] = Math.min(dp[i] + 1, b);
140+
f[i] = Math.min(f[i - 1] + 1, b);
111141
}
112142
}
113-
return dp[n];
143+
return f[n];
114144
}
115145
}
116146
```
117147

118148
```java
119149
class Solution {
120150
public int minimumDeletions(String s) {
151+
int n = s.length();
121152
int ans = 0, b = 0;
122-
for (char c : s.toCharArray()) {
123-
if (c == 'b') {
153+
for (int i = 0; i < n; ++i) {
154+
if (s.charAt(i) == 'b') {
124155
++b;
125156
} else {
126-
ans = Math.min(b, ans + 1);
157+
ans = Math.min(ans + 1, b);
158+
}
159+
}
160+
return ans;
161+
}
162+
}
163+
```
164+
165+
```java
166+
class Solution {
167+
public int minimumDeletions(String s) {
168+
int lb = 0, ra = 0;
169+
int n = s.length();
170+
for (int i = 0; i < n; ++i) {
171+
if (s.charAt(i) == 'a') {
172+
++ra;
127173
}
128174
}
175+
int ans = n;
176+
for (int i = 0; i < n; ++i) {
177+
ra -= (s.charAt(i) == 'a' ? 1 : 0);
178+
ans = Math.min(ans, lb + ra);
179+
lb += (s.charAt(i) == 'b' ? 1 : 0);
180+
}
129181
return ans;
130182
}
131183
}
@@ -138,17 +190,18 @@ class Solution {
138190
public:
139191
int minimumDeletions(string s) {
140192
int n = s.size();
141-
vector<int> dp(n + 1);
193+
int f[n + 1];
194+
memset(f, 0, sizeof(f));
142195
int b = 0;
143-
for (int i = 0; i < n; ++i) {
144-
if (s[i] == 'b') {
145-
dp[i + 1] = dp[i];
196+
for (int i = 1; i <= n; ++i) {
197+
if (s[i - 1] == 'b') {
198+
f[i] = f[i - 1];
146199
++b;
147200
} else {
148-
dp[i + 1] = min(dp[i] + 1, b);
201+
f[i] = min(f[i - 1] + 1, b);
149202
}
150203
}
151-
return dp[n];
204+
return f[n];
152205
}
153206
};
154207
```
@@ -158,34 +211,51 @@ class Solution {
158211
public:
159212
int minimumDeletions(string s) {
160213
int ans = 0, b = 0;
161-
for (char c : s) {
214+
for (char& c : s) {
162215
if (c == 'b') {
163216
++b;
164217
} else {
165-
ans = min(b, ans + 1);
218+
ans = min(ans + 1, b);
166219
}
167220
}
168221
return ans;
169222
}
170223
};
171224
```
172225

226+
```cpp
227+
class Solution {
228+
public:
229+
int minimumDeletions(string s) {
230+
int lb = 0, ra = count(s.begin(), s.end(), 'a');
231+
int ans = ra;
232+
for (char& c : s) {
233+
ra -= c == 'a';
234+
ans = min(ans, lb + ra);
235+
lb += c == 'b';
236+
}
237+
return ans;
238+
}
239+
};
240+
```
241+
173242
### **Go**
174243
175244
```go
176245
func minimumDeletions(s string) int {
177246
n := len(s)
178-
dp := make([]int, n+1)
247+
f := make([]int, n+1)
179248
b := 0
180249
for i, c := range s {
250+
i++
181251
if c == 'b' {
252+
f[i] = f[i-1]
182253
b++
183-
dp[i+1] = dp[i]
184254
} else {
185-
dp[i+1] = min(dp[i]+1, b)
255+
f[i] = min(f[i-1]+1, b)
186256
}
187257
}
188-
return dp[n]
258+
return f[n]
189259
}
190260
191261
func min(a, b int) int {
@@ -203,7 +273,7 @@ func minimumDeletions(s string) int {
203273
if c == 'b' {
204274
b++
205275
} else {
206-
ans = min(b, ans+1)
276+
ans = min(ans+1, b)
207277
}
208278
}
209279
return ans
@@ -217,6 +287,25 @@ func min(a, b int) int {
217287
}
218288
```
219289

290+
```go
291+
func minimumDeletions(s string) int {
292+
lb, ra := 0, strings.Count(s, "a")
293+
ans := ra
294+
for _, c := range s {
295+
if c == 'a' {
296+
ra--
297+
}
298+
if t := lb + ra; ans > t {
299+
ans = t
300+
}
301+
if c == 'b' {
302+
lb++
303+
}
304+
}
305+
return ans
306+
}
307+
```
308+
220309
### **...**
221310

222311
```

0 commit comments

Comments
 (0)