Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 059dc96

Browse files
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

‎solution/1700-1799/1717.Maximum Score From Removing Substrings/README.md‎

Lines changed: 120 additions & 95 deletions
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-
returnself.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)

AltStyle によって変換されたページ (->オリジナル) /