Minimum subsequences of a string A required to be appended to obtain the string B
Last Updated :
11 Mar, 2023
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++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to count the minimum
// subsequences of a string A required
// to be appended to obtain the string B
void countminOpsToConstructAString(string A,
string B)
{
// Size of the string
int N = A.length();
int i = 0;
// Maps characters to their
// respective indices
map<char, set<int> > mp;
// Insert indices of characters
// into the sets
for (i = 0; i < N; i++) {
mp[A[i]].insert(i);
}
// Stores the position of the last
// visited index in the string A.
// Initially set it to -1.
int previous = -1;
// Stores the required count
int ans = 1;
// Iterate over the characters of B
for (i = 0; i < B.length(); i++) {
char ch = B[i];
// If the character in B is
// not present in A, return -1
if (mp[ch].size() == 0) {
cout << -1;
return;
}
// Fetch the next index from B[i]'s set
auto it = mp[ch].upper_bound(previous);
// If the iterator points to
// the end of that set
if (it == mp[ch].end()) {
previous = -1;
ans++;
--i;
continue;
}
// If it doesn't point to the
// end, update previous
previous = *it;
}
// Print the answer
cout << ans;
}
// Driver Code
int main()
{
string A = "abc", B = "abac";
countminOpsToConstructAString(A, B);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to count the minimum
// subsequences of a string A required
// to be appended to obtain the string B
static void countminOpsToConstructAString(String A,
String B)
{
// Size of the string
int N = A.length();
int i = 0;
// Maps characters to their
// respective indices
Map<Character, TreeSet<Integer> > mp
= new HashMap<>();
// Insert indices of characters
// into the sets
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);
}
// Stores the position of the last
// visited index in the string A.
// Initially set it to -1.
int previous = -1;
// Stores the required count
int ans = 1;
// Iterate over the characters of B
for (i = 0; i < B.length(); i++) {
char ch = B.charAt(i);
// If the character in B is
// not present in A, return -1
if (!mp.containsKey(ch)
|| mp.get(ch).size() == 0) {
System.out.print("-1");
return;
}
// Fetch the next index from B[i]'s set
Integer it = mp.get(ch).higher(previous);
// If the iterator points to
// the end of that set
if (it == null) {
previous = -1;
ans++;
i--;
continue;
}
// If it doesn't point to the
// end, update previous
previous = it;
}
// Print the answer
System.out.print(ans);
}
// Driver Code
public static void main(String[] args)
{
String A = "abc", B = "abac";
countminOpsToConstructAString(A, B);
}
}
// Contributed by adityashae15
Python3
# Python3 program for the above approach
from bisect import bisect_right
# Function to count the minimum
# subsequences of a A required
# to be appended to obtain the B
def countminOpsToConstructAString(A, B):
# Size of the string
N = len(A)
i = 0
# Maps characters to their
# respective indices
mp = [[] for i in range(26)]
# Insert indices of characters
# into the sets
for i in range(N):
mp[ord(A[i]) - ord('a')].append(i)
# Stores the position of the last
# visited index in the A.
# Initially set it to -1.
previous = -1
# Stores the required count
ans, i = 1, 0
# Iterate over the characters of B
while i < len(B):
ch = B[i]
# If the character in B is
# not present in A, return -1
if (len(mp[ord(ch) - ord('a')]) == 0):
print(-1)
return
# Fetch the next index from B[i]'s set
it = bisect_right(mp[ord(ch) - ord('a')], previous)
# If the iterator points to
# the end of that set
if (it == len(mp[ord(ch) - ord('a')])):
previous = -1
ans += 1
# i -= 1
continue
# If it doesn't point to the
# end, update previous
previous = mp[ord(ch) - ord('a')][it]
i += 1
# Print answer
print (ans)
# Driver Code
if __name__ == '__main__':
A, B = "abc", "abac"
countminOpsToConstructAString(A, B)
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to count the minimum
// subsequences of a string A required
// to be appended to obtain the string B
static void CountminOpsToConstructAString(string A,
string B)
{
// Size of the string
int N = A.Length;
int i = 0;
// Maps characters to their
// respective indices
Dictionary<char, SortedSet<int> > mp
= new Dictionary<char, SortedSet<int> >();
// Insert indices of characters
// into the sets
for (i = 0; i < N; i++) {
if (!mp.ContainsKey(A[i])) {
mp.Add(A[i], new SortedSet<int>());
}
mp[A[i]].Add(i);
}
// Stores the position of the last
// visited index in the string A.
// Initially set it to -1.
int previous = -1;
// Stores the required count
int ans = 1;
// Iterate over the characters of B
for (i = 0; i < B.Length; i++) {
char ch = B[i];
// If the character in B is
// not present in A, return -1
if (!mp.ContainsKey(ch) || mp[ch].Count == 0) {
Console.Write("-1");
return;
}
// Fetch the next index from B[i]'s set
var view
= mp[ch].GetViewBetween(previous + 1, N);
if (view.Count == 0) {
previous = -1;
ans++;
i--;
continue;
}
int it = view.Min;
// If it doesn't point to the
// end, update previous
previous = it;
}
// Print the answer
Console.Write(ans);
}
// Driver Code
public static void Main()
{
string A = "abc", B = "abac";
CountminOpsToConstructAString(A, B);
}
}
// This code is contributed by phasing17
JavaScript
// JavaScript program for the above approach
function countminOpsToConstructAString(A, B) {
// Size of the string
const N = A.length;
let i = 0;
// Maps characters to their
// respective indices
const mp = new Array(26).fill(null).map(() => []);
// Insert indices of characters
// into the sets
for (i = 0; i < N; i++) {
mp[A.charCodeAt(i) - 'a'.charCodeAt(0)].push(i);
}
// Stores the position of the last
// visited index in the A.
// Initially set it to -1.
let previous = -1;
// Stores the required count
let ans = 1;
i = 0;
// Iterate over the characters of B
while (i < B.length) {
const ch = B[i];
// If the character in B is
// not present in A, return -1
if (mp[ch.charCodeAt(0) - 'a'.charCodeAt(0)].length == 0) {
console.log(-1);
return;
}
// Fetch the next index from B[i]'s set
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
// end, update previous
previous = mp[ch.charCodeAt(0) - 'a'.charCodeAt(0)][it];
i += 1;
}
// Print answer
console.log(ans);
}
// Driver Code
const A = "abc", B = "abac";
countminOpsToConstructAString(A, B);
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Similar Reads
Minimum deletions to make String S the Subsequence of any String in the Set D Given a string S and a set of strings D, the task is to find the minimum number of deletions required to make the string S a subsequence of any string in the set D, such that the deletion can only be performed on the substring of S. Examples: Input: string S = "abcdefg", vector<string> D = {"a
13 min read
Minimum number of subsequences required to convert one string to another Given two strings A and B consisting of only lowercase letters, the task is to find the minimum number of subsequences required from A to form B. Examples: Input: A = "abbace" B = "acebbaae" Output: 3 Explanation: Sub-sequences "ace", "bba", "ae" from string A used to form string B Input: A = "abc"
8 min read
Check if a string can be obtained by appending subsequences of another string Given two strings str1 and str2 of lengths N and M respectively, the task is to check if str2 can be formed by appending subsequences of str1 multiple times. If possible, print the minimum number of append operations required. Otherwise, print -1. Examples: Input: str1 = "abb", str2 = "ababbbbb"Outp
8 min read
Minimize operations to make string Z equal to T by appending subsequence of S Given two strings S and T, and an empty string Z, the task is to print the minimum operations required to make string Z equal to T by appending any subsequence of S at the end of Z. If it is impossible to do so, then print -1. Example: Input: S = "aabce", T="ace" Output: 1 Input: S = "abacaba", T =
10 min read
Minimum count of prefixes and suffixes of a string required to form given string Given two strings str1 and str2, the task is to find the minimum number of prefixes and suffixes of str2 required to form the string str1. If the task is not possible, return "-1".Example: Input: str1 = "HELLOWORLD", str2 = "OWORLDHELL"Output: 2Explanation: The above string can be formed as "HELL" +
10 min read