[LeetCode] 1717. Maximum Score From Removing Substrings
You are given a string s
and two integers x
and y
. You can perform two types of operations any number of times.
- Remove substring
"ab"
and gainx
points.- For example, when removing
"ab"
from"cabxbae"
it becomes"cxbae"
.
- For example, when removing
- Remove substring
"ba"
and gainy
points.- For example, when removing
"ba"
from"cabxbae"
it becomes"cabxe"
.
- For example, when removing
Return the maximum points you can gain after applying the above operations on s
.
Example 1:
Input: s = "cdbcbbaaabab", x = 4, y = 5 Output: 19 Explanation: - Remove the "ba" underlined in "cdbcbbaaabab". Now, s = "cdbcbbaaab" and 5 points are added to the score. - Remove the "ab" underlined in "cdbcbbaaab". Now, s = "cdbcbbaa" and 4 points are added to the score. - Remove the "ba" underlined in "cdbcbbaa". Now, s = "cdbcba" and 5 points are added to the score. - Remove the "ba" underlined in "cdbcba". Now, s = "cdbc" and 5 points are added to the score. Total score = 5 + 4 + 5 + 5 = 19.
Example 2:
Input: s = "aabbaaxybbaabb", x = 5, y = 4 Output: 20
Constraints:
1 <= s.length <= 105
1 <= x, y <= 104
s
consists of lowercase English letters.
删除子字符串的最大得分。
给你一个字符串 s 和两个整数 x 和 y 。你可以执行下面两种操作任意次。
删除子字符串 "ab" 并得到 x 分。
比方说,从 "cabxbae" 删除 ab ,得到 "cxbae" 。
删除子字符串"ba" 并得到 y 分。
比方说,从 "cabxbae" 删除 ba ,得到 "cabxe" 。
请返回对 s 字符串执行上面操作若干次能得到的最大得分。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-score-from-removing-substrings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题总体的思路是贪心,这里我给出一个需要用到额外空间的做法。我需要用到两个 stack。首先我预处理一下 input,这样我知道到底是 ab 组合得分更高还是 ba 组合得分更高。接着我开始遍历 input 字符串,我优先处理得分高的组合,比如如果得分高的组合是 ab 的话,当我遇到 ab 这样的子串,我优先处理,然后把它的得分加到 res 中;其他不是 ab 的字母全都加到第一个栈中,记为 stack1。
接着我再从 stack1 中把所有字符串倒出来,因为栈是先进后出的,所以如果一开始我处理的是 ab 的话,那么我现在正好可以处理 ba 这种子串了。注意 ba 从 stack 里倒出来的时候,其实是以 ab 的顺序出来的(这也就是11行和21行判断 first 和 second 的代码是一样的原因)。从 stack1 中弹出的字符我放到另一个栈,记为 stack2。这样我可以利用 stack2 获取到 ba 这种组合同时记录它的得分。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int maximumGain(String s, int x, int y) { 3 Stack<Character> stack1 = new Stack<>(); 4 Stack<Character> stack2 = new Stack<>(); 5 int res = 0; 6 int max = Math.max(x, y); 7 int min = Math.min(x, y); 8 char first = (x > y) ? 'a' : 'b'; 9 char second = (x > y) ? 'b' : 'a'; 10 for (char c : s.toCharArray()) { 11 if (!stack1.isEmpty() && stack1.peek() == first && c == second) { 12 stack1.pop(); 13 res += max; 14 } else { 15 stack1.push(c); 16 } 17 } 18 19 while (!stack1.isEmpty()) { 20 char c = stack1.pop(); 21 if (!stack2.isEmpty() && stack2.peek() == first && c == second) { 22 stack2.pop(); 23 res += min; 24 } else { 25 stack2.push(c); 26 } 27 } 28 return res; 29 } 30 }