Skip to content

Commit 059dc96

Browse files
authored
feat: add solutions to lc problem: No.1717 (doocs#3263)
1 parent 0519581 commit 059dc96

File tree

7 files changed

+336
-284
lines changed

7 files changed

+336
-284
lines changed

Diff for: solution/1700-1799/1717.Maximum Score From Removing Substrings/README.md

+120-95
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,25 @@ tags:
7474

7575
<!-- solution:start -->
7676

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)$。
7896

7997
<!-- tabs:start -->
8098

@@ -83,29 +101,24 @@ tags:
83101
```python
84102
class Solution:
85103
def maximumGain(self, s: str, x: int, y: int) -> int:
104+
a, b = "a", "b"
86105
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
90109
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:
96114
ans += x
115+
cnt1 -= 1
97116
else:
98-
stk1.append(c)
99-
while stk1:
100-
c = stk1.pop()
101-
if c != 'b':
102-
stk2.append(c)
117+
cnt2 += 1
103118
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
109122
return ans
110123
```
111124

@@ -114,37 +127,35 @@ class Solution:
114127
```java
115128
class Solution {
116129
public int maximumGain(String s, int x, int y) {
130+
char a = 'a', b = 'b';
117131
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;
119138
}
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) {
129147
ans += x;
148+
cnt1--;
130149
} else {
131-
stk1.push(c);
150+
cnt2++;
132151
}
133-
}
134-
}
135-
while (!stk1.isEmpty()) {
136-
char c = stk1.pop();
137-
if (c != 'b') {
138-
stk2.push(c);
139152
} 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;
146156
}
147157
}
158+
ans += Math.min(cnt1, cnt2) * y;
148159
return ans;
149160
}
150161
}
@@ -156,37 +167,30 @@ class Solution {
156167
class Solution {
157168
public:
158169
int maximumGain(string s, int x, int y) {
170+
char a = 'a', b = 'b';
159171
if (x < y) {
160-
reverse(s.begin(), s.end());
161-
return maximumGain(s, y, x);
172+
swap(x, y);
173+
swap(a, b);
162174
}
163-
int ans = 0;
164-
stack<char> stk1;
165-
stack<char> stk2;
175+
176+
int ans = 0, cnt1 = 0, cnt2 = 0;
166177
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) {
172182
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;
188191
}
189192
}
193+
ans += min(cnt1, cnt2) * y;
190194
return ans;
191195
}
192196
};
@@ -195,42 +199,63 @@ public:
195199
#### Go
196200

197201
```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'
199204
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
205207
}
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 {
215215
ans += x
216+
cnt1--
216217
} else {
217-
stk1 = append(stk1, s[i])
218+
cnt2++
218219
}
219-
}
220-
}
221-
for _, c := range stk1 {
222-
if c != 'a' {
223-
stk2 = append(stk2, c)
224220
} 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
231223
}
232224
}
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;
234259
}
235260
```
236261

0 commit comments

Comments
 (0)