Given two strings A and B, the task is to count the minimum number of operations required to construct the string B by following operations:
- Select a subsequence of the string A.
- Append the subsequence at the newly formed string (initially empty).
Print the minimum count of operations required. If it is impossible to make the new string equal to B by applying the given operations, then print -1.
Examples:
Input: A = “abc”, B = “abac”
Output: 2
Explanation:
Initially, C = “”.
Step 1: Select subsequence “ab” from string A and append it to the empty string C, i.e. C = “ab”.
Step 2: Select subsequence “ac” from string A and append it to the end of string C, i.e. C = “abac”.
Now, the string C is same as string B.
Therefore, count of operations required is 2.
Input: A = “geeksforgeeks”, B = “programming”
Output: -1
Approach: Follow the below steps to solve this problem:
- Initialize a Map to map characters present in the string A with their respective indices.
- For each character in string A, keep track of all of its occurrences.
- Initialize a variable, say ans, to store the count of operations required. As the number of operations must be greater than 1, set ans = 1.
- Iterate over the characters of string B and check if the character is present in the string A or not by using the Map.
- Lastly, maximize the length of the subsequence chosen from the string A for each operation.
- Finally, print the minimum operations required.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void countminOpsToConstructAString(string A,
string B)
{
int N = A.length();
int i = 0;
map< char , set< int > > mp;
for (i = 0; i < N; i++) {
mp[A[i]].insert(i);
}
int previous = -1;
int ans = 1;
for (i = 0; i < B.length(); i++) {
char ch = B[i];
if (mp[ch].size() == 0) {
cout << -1;
return ;
}
auto it = mp[ch].upper_bound(previous);
if (it == mp[ch].end()) {
previous = -1;
ans++;
--i;
continue ;
}
previous = *it;
}
cout << ans;
}
int main()
{
string A = "abc" , B = "abac" ;
countminOpsToConstructAString(A, B);
return 0;
}
|
Java
import java.util.*;
class GFG {
static void countminOpsToConstructAString(String A,
String B)
{
int N = A.length();
int i = 0 ;
Map<Character, TreeSet<Integer> > mp
= new HashMap<>();
for (i = 0 ; i < N; i++) {
if (!mp.containsKey(A.charAt(i))) {
mp.put(A.charAt(i), new TreeSet<Integer>());
}
mp.get(A.charAt(i)).add(i);
}
int previous = - 1 ;
int ans = 1 ;
for (i = 0 ; i < B.length(); i++) {
char ch = B.charAt(i);
if (!mp.containsKey(ch)
|| mp.get(ch).size() == 0 ) {
System.out.print( "-1" );
return ;
}
Integer it = mp.get(ch).higher(previous);
if (it == null ) {
previous = - 1 ;
ans++;
i--;
continue ;
}
previous = it;
}
System.out.print(ans);
}
public static void main(String[] args)
{
String A = "abc" , B = "abac" ;
countminOpsToConstructAString(A, B);
}
}
|
Python3
from bisect import bisect_right
def countminOpsToConstructAString(A, B):
N = len (A)
i = 0
mp = [[] for i in range ( 26 )]
for i in range (N):
mp[ ord (A[i]) - ord ( 'a' )].append(i)
previous = - 1
ans, i = 1 , 0
while i < len (B):
ch = B[i]
if ( len (mp[ ord (ch) - ord ( 'a' )]) = = 0 ):
print ( - 1 )
return
it = bisect_right(mp[ ord (ch) - ord ( 'a' )], previous)
if (it = = len (mp[ ord (ch) - ord ( 'a' )])):
previous = - 1
ans + = 1
continue
previous = mp[ ord (ch) - ord ( 'a' )][it]
i + = 1
print (ans)
if __name__ = = '__main__' :
A, B = "abc" , "abac"
countminOpsToConstructAString(A, B)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static void CountminOpsToConstructAString( string A,
string B)
{
int N = A.Length;
int i = 0;
Dictionary< char , SortedSet< int > > mp
= new Dictionary< char , SortedSet< int > >();
for (i = 0; i < N; i++) {
if (!mp.ContainsKey(A[i])) {
mp.Add(A[i], new SortedSet< int >());
}
mp[A[i]].Add(i);
}
int previous = -1;
int ans = 1;
for (i = 0; i < B.Length; i++) {
char ch = B[i];
if (!mp.ContainsKey(ch) || mp[ch].Count == 0) {
Console.Write( "-1" );
return ;
}
var view
= mp[ch].GetViewBetween(previous + 1, N);
if (view.Count == 0) {
previous = -1;
ans++;
i--;
continue ;
}
int it = view.Min;
previous = it;
}
Console.Write(ans);
}
public static void Main()
{
string A = "abc" , B = "abac" ;
CountminOpsToConstructAString(A, B);
}
}
|
Javascript
function countminOpsToConstructAString(A, B) {
const N = A.length;
let i = 0;
const mp = new Array(26).fill( null ).map(() => []);
for (i = 0; i < N; i++) {
mp[A.charCodeAt(i) - 'a' .charCodeAt(0)].push(i);
}
let previous = -1;
let ans = 1;
i = 0;
while (i < B.length) {
const ch = B[i];
if (mp[ch.charCodeAt(0) - 'a' .charCodeAt(0)].length == 0) {
console.log(-1);
return ;
}
const it = mp[ch.charCodeAt(0) - 'a '.charCodeAt(0)].findIndex(idx => idx > previous);
// If the iterator points to
// the end of that set
if (it == mp[ch.charCodeAt(0) - ' a '.charCodeAt(0)].length) {
previous = -1;
ans += 1;
// i -= 1
continue;
}
// If it doesn' t point to the
previous = mp[ch.charCodeAt(0) - 'a' .charCodeAt(0)][it];
i += 1;
}
console.log(ans);
}
const A = "abc" , B = "abac" ;
countminOpsToConstructAString(A, B);
|
Time Complexity: O(N * logN)
Auxiliary Space: O(N)