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:
#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 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 |
# 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# 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) |
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); |
1
Time Complexity: O(N), where N is the size of input string S.
Auxiliary Space: O(N)