47
47
48
48
** 方法一:动态规划**
49
49
50
- 定义 ` dp [i]` 表示字符串 ` s[0..i) ` 达到平衡时,需要删除的最少字符数,答案为 ` dp[n] ` 。用变量 $b$ 统计字符 ` b ` 的个数 。
50
+ 我们定义 $f [ i] $ 表示前 $i$ 个字符中,删除最少的字符数,使得字符串平衡。初始时 $f [ 0 ] =0$。答案为 $f [ n ] $ 。
51
51
52
- 遍历字符串 $s$:
52
+ 我们遍历字符串 $s$,维护变量 $b$,表示当前遍历到的位置之前的字符中,字符 $b$ 的个数。
53
53
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)$。
55
56
56
- 如果当前字符为 ` a ` ,此时,要想达到平衡,要么把前面的所有 ` b ` 都删掉,操作次数为 $b$;要么把当前的 ` a ` 删除,操作次数为 $dp [ i-1 ] +1$。取两者的最小值即可。即 $dp [ i ] =\min(b,dp [ i-1 ] +1)$。
57
+ 综上,我们可以得到状态转移方程:
57
58
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
+ $$
59
65
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$ 的长度。
61
79
62
80
<!-- tabs:start -->
63
81
69
87
class Solution :
70
88
def minimumDeletions (self , s : str ) -> int :
71
89
n = len (s)
72
- dp = [0 ] * (n + 1 )
90
+ f = [0 ] * (n + 1 )
73
91
b = 0
74
92
for i, c in enumerate (s, 1 ):
75
93
if c == ' b' :
76
- dp [i] = dp [i - 1 ]
94
+ f [i] = f [i - 1 ]
77
95
b += 1
78
96
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]
81
99
```
82
100
83
101
``` python
@@ -88,7 +106,19 @@ class Solution:
88
106
if c == ' b' :
89
107
b += 1
90
108
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'
92
122
return ans
93
123
```
94
124
@@ -100,32 +130,54 @@ class Solution:
100
130
class Solution {
101
131
public int minimumDeletions (String s ) {
102
132
int n = s. length();
103
- int [] dp = new int [n + 1 ];
133
+ int [] f = new int [n + 1 ];
104
134
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 ];
108
138
++ b;
109
139
} else {
110
- dp[i + 1 ] = Math . min(dp[i ] + 1 , b);
140
+ f[i ] = Math . min(f[i - 1 ] + 1 , b);
111
141
}
112
142
}
113
- return dp [n];
143
+ return f [n];
114
144
}
115
145
}
116
146
```
117
147
118
148
``` java
119
149
class Solution {
120
150
public int minimumDeletions (String s ) {
151
+ int n = s. length();
121
152
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' ) {
124
155
++ b;
125
156
} 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;
127
173
}
128
174
}
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
+ }
129
181
return ans;
130
182
}
131
183
}
@@ -138,17 +190,18 @@ class Solution {
138
190
public:
139
191
int minimumDeletions(string s) {
140
192
int n = s.size();
141
- vector<int > dp(n + 1);
193
+ int f[ n + 1] ;
194
+ memset(f, 0, sizeof(f));
142
195
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 ] ;
146
199
++b;
147
200
} else {
148
- dp [ i + 1 ] = min(dp [ i ] + 1, b);
201
+ f [ i ] = min(f [ i - 1 ] + 1, b);
149
202
}
150
203
}
151
- return dp [ n] ;
204
+ return f [ n] ;
152
205
}
153
206
};
154
207
```
@@ -158,34 +211,51 @@ class Solution {
158
211
public:
159
212
int minimumDeletions(string s) {
160
213
int ans = 0, b = 0;
161
- for (char c : s) {
214
+ for (char& c : s) {
162
215
if (c == 'b') {
163
216
++b;
164
217
} else {
165
- ans = min(b, ans + 1);
218
+ ans = min(ans + 1, b );
166
219
}
167
220
}
168
221
return ans;
169
222
}
170
223
};
171
224
```
172
225
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
+
173
242
### **Go**
174
243
175
244
```go
176
245
func minimumDeletions(s string) int {
177
246
n := len(s)
178
- dp := make ([]int , n+1 )
247
+ f := make([]int, n+1)
179
248
b := 0
180
249
for i, c := range s {
250
+ i++
181
251
if c == 'b' {
252
+ f[i] = f[i-1]
182
253
b++
183
- dp[i+1 ] = dp[i]
184
254
} else {
185
- dp[i+ 1 ] = min (dp[i ]+1 , b)
255
+ f[i ] = min(f[i-1 ]+1, b)
186
256
}
187
257
}
188
- return dp [n]
258
+ return f [n]
189
259
}
190
260
191
261
func min(a, b int) int {
@@ -203,7 +273,7 @@ func minimumDeletions(s string) int {
203
273
if c == ' b' {
204
274
b++
205
275
} else {
206
- ans = min (b, ans+1 )
276
+ ans = min (ans+1 , b )
207
277
}
208
278
}
209
279
return ans
@@ -217,6 +287,25 @@ func min(a, b int) int {
217
287
}
218
288
```
219
289
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
+
220
309
### ** ...**
221
310
222
311
```
0 commit comments