You are given a string s
and two integers x
and y
. You can perform two types of operations any number of times.
"ab"
and gain x
points.
"ab"
from "cabxbae"
it becomes "cxbae"
."ba"
and gain y
points.
"ba"
from "cabxbae"
it becomes "cabxe"
.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.This problem involves finding the maximum score achievable by removing substrings "ab" and "ba" from a given string, with different scores assigned to each. The optimal strategy is greedy: prioritize removing the substring that yields a higher score.
Approach:
Greedy Strategy: We first determine which substring ("ab" or "ba") yields a higher score. We prioritize removing this higher-scoring substring first. This is because removing one substring might create opportunities to remove more of the same type of substring.
Iteration: We iterate through the string. If we encounter the first character of the higher-scoring substring, we push it onto a stack. If we encounter the second character of the higher-scoring substring, and the stack's top element is the first character, we pop the top element from the stack (representing removing the higher-scoring substring) and update our score. Otherwise, we push the character onto the stack.
Handling the Other Substring: After processing the higher-scoring substring, we repeat the process for the other substring. We iterate through the remaining string (represented by the stack) and remove the lower-scoring substrings.
Score Calculation: The total score is the sum of scores obtained from removing both types of substrings.
Time and Space Complexity:
Code (Python):
def maximumGain(s, x, y):
"""
Calculates the maximum score by removing substrings "ab" and "ba".
Args:
s: The input string.
x: The score for removing "ab".
y: The score for removing "ba".
Returns:
The maximum score achievable.
"""
def remove_substring(stack, char1, char2, score):
new_stack = []
count = 0
for char in stack:
if new_stack and new_stack[-1] == char1 and char == char2:
new_stack.pop()
count += 1
else:
new_stack.append(char)
return new_stack, count * score
stack = list(s)
if x > y:
stack, count_x = remove_substring(stack, 'a', 'b', x)
stack, count_y = remove_substring(stack, 'b', 'a', y)
else:
stack, count_y = remove_substring(stack, 'b', 'a', y)
stack, count_x = remove_substring(stack, 'a', 'b', x)
return count_x + count_y
Code (JavaScript):
function maximumGain(s, x, y) {
const removeSubstring = (stack, char1, char2, score) => {
const newStack = [];
let count = 0;
for (const char of stack) {
if (newStack.length > 0 && newStack[newStack.length - 1] === char1 && char === char2) {
newStack.pop();
count++;
} else {
newStack.push(char);
}
}
return [newStack, count * score];
};
let stack = s.split("");
if (x > y) {
[stack, let countX] = removeSubstring(stack, 'a', 'b', x);
[stack, let countY] = removeSubstring(stack, 'b', 'a', y);
} else {
[stack, let countY] = removeSubstring(stack, 'b', 'a', y);
[stack, let countX] = removeSubstring(stack, 'a', 'b', x);
}
return countX + countY;
}
The JavaScript and Python code demonstrate the same approach, prioritizing the higher-scoring substring removal. The remove_substring
or removeSubstring
function efficiently handles the removal process using a stack. The overall solution is clear, concise, and optimized for performance.