74
74
75
75
<!-- solution:start -->
76
76
77
- ### 方法一
77
+ ### 方法一:贪心
78
+
79
+ 我们不妨假设子字符串 "ab" 的得分总是不低于子字符串 "ba" 的得分,如果不是,我们可以交换 "a" 和 "b",同时交换 $x$ 和 $y$。
80
+
81
+ 接下来,我们只需要考虑字符串中只包含 "a" 和 "b" 的情况。如果字符串中包含其他字符,我们可以将其视为一个分割点,将字符串分割成若干个只包含 "a" 和 "b" 的子字符串,然后分别计算每个子字符串的得分。
82
+
83
+ 我们观察发现,对于一个只包含 "a" 和 "b" 的子字符串,无论采取什么样的操作,最后一定只剩下一种字符,或者空串。由于每次操作都会同时删除一个 "a" 和一个 "b",因此总的操作次数一定是固定的。我们可以贪心地先删除 "ab",再删除 "ba",这样可以保证得分最大。
84
+
85
+ 因此,我们可以使用两个变量 $\textit{cnt1}$ 和 $\textit{cnt2}$ 分别记录 "a" 和 "b" 的数量,然后遍历字符串,根据当前字符的不同情况更新 $\textit{cnt1}$ 和 $\textit{cnt2}$,并计算得分。
86
+
87
+ 对于当前遍历到的字符 $c$:
88
+
89
+ - 如果 $c$ 是 "a",由于要先删除 "ab",因此此时我们不消除该字符,只增加 $\textit{cnt1}$;
90
+ - 如果 $c$ 是 "b",如果此时 $\textit{cnt1} > 0$,我们可以消除一个 "ab",并增加 $x$ 分,否则我们只能增加 $\textit{cnt2}$;
91
+ - 如果 $c$ 是其他字符,那么对于该子字符串,我们剩下了一个 $\textit{cnt2}$ 个 "b" 和 $\textit{cnt1}$ 个 "a",我们可以消除 $\min(\textit{cnt1}, \textit{cnt2})$ 个 "ab",并增加 $y$ 分。
92
+
93
+ 遍历结束后,我们还需要额外处理一下剩余的 "ab",增加若干个 $y$ 分。
94
+
95
+ 时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(1)$。
78
96
79
97
<!-- tabs:start -->
80
98
@@ -83,29 +101,24 @@ tags:
83
101
``` python
84
102
class Solution :
85
103
def maximumGain (self , s : str , x : int , y : int ) -> int :
104
+ a, b = " a" , " b"
86
105
if x < y:
87
- return self .maximumGain(s[:: - 1 ] , y, x)
88
- ans = 0
89
- stk1, stk2 = [], []
106
+ x , y = y , x
107
+ a, b = b, a
108
+ ans = cnt1 = cnt2 = 0
90
109
for c in s:
91
- if c != ' b' :
92
- stk1.append(c)
93
- else :
94
- if stk1 and stk1[- 1 ] == ' a' :
95
- stk1.pop()
110
+ if c == a:
111
+ cnt1 += 1
112
+ elif c == b:
113
+ if cnt1:
96
114
ans += x
115
+ cnt1 -= 1
97
116
else :
98
- stk1.append(c)
99
- while stk1:
100
- c = stk1.pop()
101
- if c != ' b' :
102
- stk2.append(c)
117
+ cnt2 += 1
103
118
else :
104
- if stk2 and stk2[- 1 ] == ' a' :
105
- stk2.pop()
106
- ans += y
107
- else :
108
- stk2.append(c)
119
+ ans += min (cnt1, cnt2) * y
120
+ cnt1 = cnt2 = 0
121
+ ans += min (cnt1, cnt2) * y
109
122
return ans
110
123
```
111
124
@@ -114,37 +127,35 @@ class Solution:
114
127
``` java
115
128
class Solution {
116
129
public int maximumGain (String s , int x , int y ) {
130
+ char a = ' a' , b = ' b' ;
117
131
if (x < y) {
118
- return maximumGain(new StringBuilder (s). reverse(). toString(), y, x);
132
+ int t = x;
133
+ x = y;
134
+ y = t;
135
+ char c = a;
136
+ a = b;
137
+ b = c;
119
138
}
120
- int ans = 0 ;
121
- Deque<Character > stk1 = new ArrayDeque<> ();
122
- Deque<Character > stk2 = new ArrayDeque<> ();
123
- for (char c : s. toCharArray()) {
124
- if (c != ' b' ) {
125
- stk1. push(c);
126
- } else {
127
- if (! stk1. isEmpty() && stk1. peek() == ' a' ) {
128
- stk1. pop();
139
+ int ans = 0 , cnt1 = 0 , cnt2 = 0 ;
140
+ int n = s. length();
141
+ for (int i = 0 ; i < n; ++ i) {
142
+ char c = s. charAt(i);
143
+ if (c == a) {
144
+ cnt1++ ;
145
+ } else if (c == b) {
146
+ if (cnt1 > 0 ) {
129
147
ans += x;
148
+ cnt1-- ;
130
149
} else {
131
- stk1 . push(c) ;
150
+ cnt2 ++ ;
132
151
}
133
- }
134
- }
135
- while (! stk1. isEmpty()) {
136
- char c = stk1. pop();
137
- if (c != ' b' ) {
138
- stk2. push(c);
139
152
} else {
140
- if (! stk2. isEmpty() && stk2. peek() == ' a' ) {
141
- stk2. pop();
142
- ans += y;
143
- } else {
144
- stk2. push(c);
145
- }
153
+ ans += Math . min(cnt1, cnt2) * y;
154
+ cnt1 = 0 ;
155
+ cnt2 = 0 ;
146
156
}
147
157
}
158
+ ans += Math . min(cnt1, cnt2) * y;
148
159
return ans;
149
160
}
150
161
}
@@ -156,37 +167,30 @@ class Solution {
156
167
class Solution {
157
168
public:
158
169
int maximumGain(string s, int x, int y) {
170
+ char a = 'a', b = 'b';
159
171
if (x < y) {
160
- reverse(s.begin(), s.end() );
161
- return maximumGain(s, y, x );
172
+ swap(x, y );
173
+ swap(a, b );
162
174
}
163
- int ans = 0;
164
- stack<char > stk1;
165
- stack<char > stk2;
175
+
176
+ int ans = 0, cnt1 = 0, cnt2 = 0;
166
177
for (char c : s) {
167
- if (c != 'b')
168
- stk1.push(c);
169
- else {
170
- if (!stk1.empty() && stk1.top() == 'a') {
171
- stk1.pop();
178
+ if (c == a) {
179
+ cnt1++;
180
+ } else if (c == b) {
181
+ if (cnt1) {
172
182
ans += x;
173
- } else
174
- stk1.push(c);
175
- }
176
- }
177
- while (!stk1.empty()) {
178
- char c = stk1.top();
179
- stk1.pop();
180
- if (c != 'b')
181
- stk2.push(c);
182
- else {
183
- if (!stk2.empty() && stk2.top() == 'a') {
184
- stk2.pop();
185
- ans += y;
186
- } else
187
- stk2.push(c);
183
+ cnt1--;
184
+ } else {
185
+ cnt2++;
186
+ }
187
+ } else {
188
+ ans += min(cnt1, cnt2) * y;
189
+ cnt1 = 0;
190
+ cnt2 = 0;
188
191
}
189
192
}
193
+ ans += min(cnt1, cnt2) * y;
190
194
return ans;
191
195
}
192
196
};
@@ -195,42 +199,63 @@ public:
195
199
#### Go
196
200
197
201
``` go
198
- func maximumGain(s string, x int, y int) int {
202
+ func maximumGain (s string , x int , y int ) (ans int ) {
203
+ a , b := ' a' , ' b'
199
204
if x < y {
200
- t := []rune(s)
201
- for i, j := 0, len(t)-1; i < j; i, j = i+1, j-1 {
202
- t[i], t[j] = t[j], t[i]
203
- }
204
- return maximumGain(string(t), y, x)
205
+ x, y = y, x
206
+ a, b = b, a
205
207
}
206
- ans := 0
207
- var stk1 []byte
208
- var stk2 []byte
209
- for i := range s {
210
- if s[i] != 'b' {
211
- stk1 = append(stk1, s[i])
212
- } else {
213
- if len(stk1) > 0 && stk1[len(stk1)-1] == 'a' {
214
- stk1 = stk1[0 : len(stk1)-1]
208
+
209
+ var cnt1 , cnt2 int
210
+ for _ , c := range s {
211
+ if c == a {
212
+ cnt1++
213
+ } else if c == b {
214
+ if cnt1 > 0 {
215
215
ans += x
216
+ cnt1--
216
217
} else {
217
- stk1 = append(stk1, s[i])
218
+ cnt2++
218
219
}
219
- }
220
- }
221
- for _, c := range stk1 {
222
- if c != 'a' {
223
- stk2 = append(stk2, c)
224
220
} else {
225
- if len(stk2) > 0 && stk2[len(stk2)-1] == 'b' {
226
- stk2 = stk2[0 : len(stk2)-1]
227
- ans += y
228
- } else {
229
- stk2 = append(stk2, c)
230
- }
221
+ ans += min (cnt1, cnt2) * y
222
+ cnt1, cnt2 = 0 , 0
231
223
}
232
224
}
233
- return ans
225
+ ans += min (cnt1, cnt2) * y
226
+ return
227
+ }
228
+ ```
229
+
230
+ #### TypeScript
231
+
232
+ ``` ts
233
+ function maximumGain(s : string , x : number , y : number ): number {
234
+ let [a, b] = [' a' , ' b' ];
235
+ if (x < y ) {
236
+ [x , y ] = [y , x ];
237
+ [a , b ] = [b , a ];
238
+ }
239
+
240
+ let [ans, cnt1, cnt2] = [0 , 0 , 0 ];
241
+ for (let c of s ) {
242
+ if (c === a ) {
243
+ cnt1 ++ ;
244
+ } else if (c === b ) {
245
+ if (cnt1 ) {
246
+ ans += x ;
247
+ cnt1 -- ;
248
+ } else {
249
+ cnt2 ++ ;
250
+ }
251
+ } else {
252
+ ans += Math .min (cnt1 , cnt2 ) * y ;
253
+ cnt1 = 0 ;
254
+ cnt2 = 0 ;
255
+ }
256
+ }
257
+ ans += Math .min (cnt1 , cnt2 ) * y ;
258
+ return ans ;
234
259
}
235
260
```
236
261
0 commit comments