Open In App

Minimizing Removal of Characters for Partitioning into three substrings that contain ‘a’ and ‘b’ characters only.

Last Updated : 16 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S of length N, find the minimum characters we need to remove such that the resultant string can be cut into 3 strings (possibly empty) without changing the order of letters, where the first and the third string contains only letter “a” and second string contains only “b“.

Examples:

Input: S = “bab”
Output: 1
Explanation: We can remove the first “b” and then divide the string as: “a”, “b” and “”.

Input: S = “abba”
Output: 0
Explanation: No need to remove any character as we can divide the string as: “a”, “bb” and “a”.

Approach: The problem can be solved using the following approach:

The problem can be solved using Dynamic Programming. We can calculate the minimum number of deletions by taking the length of the original string and subtracting the length of longest possible string which can be divided into 3 parts such that the first and third part contains only letter “a” and the second part contains only letter “b”.
Let’s say we are at any index i, then we have three choices for the current character:

  • The character belongs to the first part: The character should be “a” and the previous character should also belong to first part.
  • The character belongs to the second part: The character should be “a” and the previous character can be in the first or the second part.
  • The character belongs to the third part: The character should be “a” and the previous character can be from the second or third part.

Maintain a 2D array dp[][] of size N X 3, such that dp[i][0] stores the longest length if the ith character belongs to the first part, dp[i][1] stores the longest length if the ith character belongs to the second part and dp[i][2] stores the longest length if the ith character belongs to the third part.

Steps to solve the problem:

  • Maintain a 2D array dp[][] of size NX3.
  • For every index i > 0,
    • Set dp[i][0] = dp[i – 1][0] + (S[i] == ‘a’)
    • Set dp[i][1] = max(dp[i – 1][0], dp[i – 1][1]) + (S[i] == ‘b’)
    • Set dp[i][2] = max(dp[i – 1][1], dp[i – 1][2]) + (S[i] == ‘a’)
  • Return length – maximum among dp[N – 1][0], dp[N – 1][1] and dp[N – 1][2].

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum characters to be removed
// to split the string into three parts as described in the
// problem
int findMinCharsToRemove(string S)
{
    int N = S.length();
      // 2D dp[][] array
    vector<vector<int>> dp(N, vector<int>(3, 0));
   
      // Initializing the starting states
      dp[0][0] = S[0] == 'a';
      dp[0][1] = S[0] == 'b';
      dp[0][2] = S[0] == 'a';
       
      // DP transitions
      for(int i = 1; i < N; i ++) {
        dp[i][0] = dp[i - 1][0] + (S[i] == 'a');
          dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]) + (S[i] == 'b');
          dp[i][2] = max(dp[i - 1][1], dp[i - 1][2]) + (S[i] == 'a');
    }
       
      return N - max({dp[N - 1][0], dp[N - 1][1], dp[N - 1][2]});
}
 
int main()
{
    // Input string from the user
    string S = "bab";   
   
    // Find and output the minimum characters to be removed
    int result = findMinCharsToRemove(S);
    cout << result << endl;
 
    return 0;
}


Java




// Java program for the above approach
import java.util.Arrays;
 
public class GFG {
    // Function to find the minimum characters to be removed
    // to split the string into three parts as described in
    // the problem
    static int findMinCharsToRemove(String S)
    {
        int N = S.length();
 
        // 2D dp[][] array
        int[][] dp = new int[N][3];
 
        // Initializing the starting states
        dp[0][0] = (S.charAt(0) == 'a') ? 1 : 0;
        dp[0][1] = (S.charAt(0) == 'b') ? 1 : 0;
        dp[0][2] = (S.charAt(0) == 'a') ? 1 : 0;
 
        // DP transitions
        for (int i = 1; i < N; i++) {
            dp[i][0] = dp[i - 1][0]
                       + (S.charAt(i) == 'a' ? 1 : 0);
            dp[i][1] = Math.max(dp[i - 1][0], dp[i - 1][1])
                       + (S.charAt(i) == 'b' ? 1 : 0);
            dp[i][2] = Math.max(dp[i - 1][1], dp[i - 1][2])
                       + (S.charAt(i) == 'a' ? 1 : 0);
        }
 
        return N
            - Math.max(
                dp[N - 1][0],
                Math.max(dp[N - 1][1], dp[N - 1][2]));
    }
 
    public static void main(String[] args)
    {
        // Input string from the user
        String S = "bab";
 
        // Find and output the minimum characters to be
        // removed
        int result = findMinCharsToRemove(S);
        System.out.println(result);
    }
}
 
// This code is contributed by Susobhan Akhuli


Python3




# Python program for the above approach
def find_min_chars_to_remove(S):
    N = len(S)
    # 2D dp[][] array
    dp = [[0] * 3 for _ in range(N)]
 
    # Initializing the starting states
    dp[0][0] = 1 if S[0] == 'a' else 0
    dp[0][1] = 1 if S[0] == 'b' else 0
    dp[0][2] = 1 if S[0] == 'a' else 0
     
    # DP transitions
    for i in range(1, N):
        dp[i][0] = dp[i - 1][0] + (S[i] == 'a')
        dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]) + (S[i] == 'b')
        dp[i][2] = max(dp[i - 1][1], dp[i - 1][2]) + (S[i] == 'a')
     
    return N - max(dp[N - 1])
 
# Input string
S = "bab"
 
# Find and output the minimum characters to be removed
result = find_min_chars_to_remove(S)
print(result)
 
# This code is contributed by Susobhan Akhuli


C#




// C# Implementation
 
using System;
 
class GFG {
    // Function to find the minimum characters to be removed
    // to split the string into three parts as described in
    // the problem
    static int FindMinCharsToRemove(string S)
    {
        int N = S.Length;
 
        // 2D dp[][] array
        int[,] dp = new int[N, 3];
 
        // Initializing the starting states
        dp[0, 0] = (S[0] == 'a') ? 1 : 0;
        dp[0, 1] = (S[0] == 'b') ? 1 : 0;
        dp[0, 2] = (S[0] == 'a') ? 1 : 0;
 
        // DP transitions
        for (int i = 1; i < N; i++) {
            dp[i, 0] = dp[i - 1, 0] + (S[i] == 'a' ? 1 : 0);
            dp[i, 1] = Math.Max(dp[i - 1, 0], dp[i - 1, 1]) + (S[i] == 'b' ? 1 : 0);
            dp[i, 2] = Math.Max(dp[i - 1, 1], dp[i - 1, 2]) + (S[i] == 'a' ? 1 : 0);
        }
 
        return N - Math.Max(dp[N - 1, 0], Math.Max(dp[N - 1, 1], dp[N - 1, 2]));
    }
 
    public static void Main(string[] args)
    {
        // Input string from the user
        string S = "bab";
 
        // Find and output the minimum characters to be
        // removed
        int result = FindMinCharsToRemove(S);
        Console.WriteLine(result);
    }
}
// This code is contributed by Tapesh(tapeshdu420)


Javascript




function GFG(S) {
    const N = S.length;
    // 2D dp[][] array
    const dp = new Array(N).fill().map(() => new Array(3).fill(0));
    // Initializing the starting states
    dp[0][0] = S[0] === 'a' ? 1 : 0;
    dp[0][1] = S[0] === 'b' ? 1 : 0;
    dp[0][2] = S[0] === 'a' ? 1 : 0;
    // DP transitions
    for (let i = 1; i < N; i++) {
        dp[i][0] = dp[i - 1][0] + (S[i] === 'a' ? 1 : 0);
        dp[i][1] = Math.max(dp[i - 1][0], dp[i - 1][1]) + (S[i] === 'b' ? 1 : 0);
        dp[i][2] = Math.max(dp[i - 1][1], dp[i - 1][2]) + (S[i] === 'a' ? 1 : 0);
    }
    // Return the minimum characters to be removed
    return N - Math.max(dp[N - 1][0], dp[N - 1][1], dp[N - 1][2]);
}
 
// Input string
const S = "bab";
const result = GFG(S);
console.log(result);


Output

1

Time Complexity: O(N), where N is the size of input string S.
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads