Maximum Score From Removing Substrings

Updated on 11 June, 2025
Maximum Score From Removing Substrings header image

Problem Statement

Given a string s along with two integers x and y, you have the ability to perform two types of substring removal operations to accumulate points. You can repeatedly remove the substring "ab" from s to gain x points or remove the substring "ba" to gain y points. Each time a substring is removed, the string s is shortened, and substrings cannot be overlapped during a single operation. The goal is to determine the maximum number of points that can be accumulated by applying these removal operations appropriately on the string s.

Examples

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.

Approach and Intuition

  1. Understanding the Problem Constraints:

    • The length of the string can be quite large, up to 105 characters. This implies that a highly optimized approach is necessary to avoid timeout errors.
    • The operations can be performed any number of times, which suggests the possibility of intricate looping or recursive solutions, possibly augmented with memoization.
  2. Optimizing the Order of Operations:

    • Since removing one type of substring might create new opportunities to remove the other type, the order in which substrings are removed can affect the total score.
    • The intuitive approach could be to always remove the substring that offers the higher points first. However, this may not always yield the maximum total points due to the dynamic nature of the remaining string after each operation.
  3. Approach to Solution:

    • One potential method to tackle the problem could be to perform a greedy approach:
      • Parse through the string while maintaining a count of possible "ab" and "ba" substrings.
      • Depending on which operation yields more points (x vs y), prioritize its removal.
      • Adjust the counts of "ab" and "ba" substrings dynamically as the string changes with each removal.
    • Another approach could be dynamic programming:
      • Define states that represent the maximum score attainable from the first i characters of s.
      • Use transition states based on whether an "ab" or "ba" is removed, and compute the maximum possible points from prior states.
  4. Edge Cases & Considerations:

    • If x equals y, one might simplify the solution by always opting for the first removable substring found in any scan of s.
    • Consider the case where no "ab" or "ba" substrings exist; the score would then be 0.
    • What if the string has overlapping substrings like "aba" - determining which removal leads to the best outcome would be key.

This solution needs to be implemented while ensuring time complexity is kept as efficient as possible to handle the upper constraint of the input size.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int maxScore(string str, int p, int q) {
        // Invert values if p < q to prioritize higher score
        if (p < q) {
            swap(p, q);
            reverse(str.begin(), str.end());
        }

        int countA = 0, countB = 0, score = 0;

        for (char c : str) {
            if (c == 'a') {
                ++countA;
            } else if (c == 'b') {
                if (countA > 0) {
                    --countA;
                    score += p;
                } else {
                    ++countB;
                }
            } else {
                // Handle sequences of 'a's and 'b's
                score += min(countB, countA) * q;
                countA = countB = 0;
            }
        }
        // Add scores for remaining pairs
        score += min(countB, countA) * q;

        return score;
    }
};

The problem in question requires calculating the maximum score by removing specific substrings from a given string, using C++ language. The provided code implements a solution for maximizing the score by removing ab with a score of p and ba with a score of q substrings from the input string. The approach adjusts to always start with the removal of the substring associated with the higher score due to a strategic initial processing of the input data if necessary.

  • Adjust Initial Conditions: Begin by checking whether p < q. If this condition holds true, the score values and the string are inverted using swap for p and q and reverse for the string itself. This adjustment ensures that the algorithm always processes the substring with the higher score first.

  • Initialize Counters and Score: Three variables are initialized: countA and countB to count the occurrences of 'a' and 'b', respectively, before they form a valid ab or ba pair, and score to keep track of the accumulated points.

  • Iterate Through Characters: Loop through each character of the string. Increase countA when encountering an 'a'. For 'b', check if there is any preceding 'a'. If yes, a valid ab formation is decremented from countA and adds p to score; if not, increment countB.

  • Handle Remaining Characters: After the loop, there may be unfinished business with leftover 'a's and 'b's that can still form pairs. Calculate the score for these remaining valid pairs using the minimum of countA and countB multiplied by q.

  • Return the Final Score: The accumulated score is the result of the function, representing the maximum score possible under the conditions set by p and q.

This algorithm efficiently factors in priority based on the score comparison of ab versus ba, optimizes the count and pairing process through straightforward conditions, and ensures no potential pairings are left out by the end of processing, resulting in the maximum achievable score.

java
class Solution {

    public int getMaxScore(String inputString, int pointsAB, int pointsBA) {
        // Check to prioritize higher points
        if (pointsAB < pointsBA) {
            // Value swap
            int tempPoints = pointsAB;
            pointsAB = pointsBA;
            pointsBA = tempPoints;
            // Reverse string if "ba" points are higher
            inputString = new StringBuilder(inputString).reverse().toString();
        }

        int countA = 0, countB = 0, score = 0;

        for (int index = 0; index < inputString.length(); index++) {
            char current = inputString.charAt(index);

            if (current == 'a') {
                countA++;
            } else if (current == 'b') {
                if (countA > 0) {
                    // Form "ab" and score
                    countA--;
                    score += pointsAB;
                } else {
                    // Otherwise increment 'b' count
                    countB++;
                }
            } else {
                // Handle other characters and score for "ba"
                score += Math.min(countB, countA) * pointsBA;
                countA = countB = 0;
            }
        }

        // Score any final "ba" combinations
        score += Math.min(countB, countA) * pointsBA;

        return score;
    }
}

This Java program is designed to calculate the maximum score from removing subsequences "ab" or "ba" from a given string, where each subsequence has its respective point value. Here's how you can understand and implement the provided solution:

  • First, identify which substring, either "ab" or "ba", offers higher points. If "ba" has higher points, the solution involves reversing the input string to maximize the point accrual based on the sequence order.
  • Create variables countA and countB to keep track of the counts of 'a' and 'b' respectively as you iterate over the characters of the string.
  • Use a loop to traverse the string character by character, incrementing countA when an 'a' is encountered, and attempting to form a "ab" combination when a 'b' is encountered. If an 'a' has been counted before a 'b', decrement countA and add the points for "ab" to score; otherwise, increment countB.
  • For characters that are neither 'a' nor 'b', calculate and add to the score using the smaller of countA or countB multiplied by pointsBA.
  • At each step, reset countA and countB to zero once the score for "ba" is calculated.
  • After the loop ends, calculate and add any remaining "ba" combinations that might exist using the left-over counts of countA and countB.

This approach effectively leverages string manipulation and simple arithmetic to maximize the score based on substring removal, ensuring that the sequence with the higher point value is prioritized for potential maximum scoring.

python
class Solution:
    def getMaxPoints(self, text: str, points_ab: int, points_ba: int) -> int:
        # If "ba" point is higher, adjust the string and values
        if points_ab < points_ba:
            text = text[::-1]
            points_ab, points_ba = points_ba, points_ab

        count_a, count_b, score = 0, 0, 0

        for char in text:
            if char == "a":
                count_a += 1
            elif char == "b":
                if count_a > 0:
                    count_a -= 1
                    score += points_ab
                else:
                    count_b += 1
            else:
                score += min(count_b, count_a) * points_ba
                count_a = count_b = 0
        
        score += min(count_b, count_a) * points_ba

        return score

The provided Python code defines a method getMaxPoints for the Solution class that calculates the maximum score possible from removing substrings "ab" and "ba" from a given string, where each removal adds a specified number of points to the score.

Here's the breakdown of the code logic:

  • The function first checks which of the substring removals -- "ab" or "ba" -- has a higher assigned point value. If "ba" has a higher point value, the text is reversed, and the values of points_ab and points_ba are swapped. This ensures that the substring with the higher point value is always prioritized in the main loop.

  • It then iterates through each character of the processed string, maintaining counters (count_a for 'a' and count_b for 'b') and a running score.

  • During the iteration:

    • If the current character is 'a', it increments count_a.
    • If it is 'b' and there is already a count of 'a' (count_a > 0), it decrements count_a and adds points_ab to score, indicating removal of "ab".
    • If it is 'b' and count_a is zero, it increments count_b.
    • Any other character triggers the addition of points for minimum of count_a and count_b times points_ba to score and both counters are reset.
  • After the loop, adds the scores for remaining 'a' and 'b' pairs as min(count_b, count_a) * points_ba.

By efficiently deciding which substring to remove more aggressively based on their point values, and managing counts of 'a' and 'b' appropriately, this algorithm calculates the score in a single pass through the string, resulting in an efficient solution.

Comments

No comments yet.