Minimizing Removal of Characters for Partitioning into three substrings that contain ‘a’ and ‘b’ characters only.
Last Updated :
16 Feb, 2024
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;
int findMinCharsToRemove(string S)
{
int N = S.length();
vector<vector< int >> dp(N, vector< int >(3, 0));
dp[0][0] = S[0] == 'a' ;
dp[0][1] = S[0] == 'b' ;
dp[0][2] = S[0] == 'a' ;
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()
{
string S = "bab" ;
int result = findMinCharsToRemove(S);
cout << result << endl;
return 0;
}
|
Java
import java.util.Arrays;
public class GFG {
static int findMinCharsToRemove(String S)
{
int N = S.length();
int [][] dp = new int [N][ 3 ];
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 ;
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)
{
String S = "bab" ;
int result = findMinCharsToRemove(S);
System.out.println(result);
}
}
|
Python3
def find_min_chars_to_remove(S):
N = len (S)
dp = [[ 0 ] * 3 for _ in range (N)]
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
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 ])
S = "bab"
result = find_min_chars_to_remove(S)
print (result)
|
C#
using System;
class GFG {
static int FindMinCharsToRemove( string S)
{
int N = S.Length;
int [,] dp = new int [N, 3];
dp[0, 0] = (S[0] == 'a' ) ? 1 : 0;
dp[0, 1] = (S[0] == 'b' ) ? 1 : 0;
dp[0, 2] = (S[0] == 'a' ) ? 1 : 0;
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)
{
string S = "bab" ;
int result = FindMinCharsToRemove(S);
Console.WriteLine(result);
}
}
|
Javascript
function GFG(S) {
const N = S.length;
const dp = new Array(N).fill().map(() => new Array(3).fill(0));
dp[0][0] = S[0] === 'a' ? 1 : 0;
dp[0][1] = S[0] === 'b' ? 1 : 0;
dp[0][2] = S[0] === 'a' ? 1 : 0;
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 N - Math.max(dp[N - 1][0], dp[N - 1][1], dp[N - 1][2]);
}
const S = "bab" ;
const result = GFG(S);
console.log(result);
|
Time Complexity: O(N), where N is the size of input string S.
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...