Given two strings A and B, the task is to find the smallest substring of A having B as a subsequence.
Examples:
Input: A = “abcdefababaef”, B = “abf”
Output: 5
Explanation:
Smallest substring of A having B as subsequence is abcdef.
Therefore, the required length is 5.Input: A = “abcdefababaef”, B = “aef”
Output: 3
Approach: Follow the steps below to solve the problem:
- Store all the indices of the characters of A which are also present in B in a Map CharacterIndex.
- Traverse over all the characters of string B.
- Check if the first character of string B is present in the string A or not:
- If found to be true, then initialize two variables firstVar and lastVar with the index of the first occurrence of B[0] in the string A.
- After updating the values, remove that character from the Map CharacterIndex.
- Otherwise, no further substring is possible.
- For the remaining characters of B, check if the character is present in the string A or not. If found to be true, traverse through all the occurrences of that character in the string A and if the index of that character in the string A exceeds lastVar, then update the lastVar with that index. Otherwise, no further substring is possible.
- If B is completely traversed, update answer with the difference between firstVar and the lastVar.
- Print the final minimized answer.
Below is the implementation of the above approach:
C++
// C++ program to implement // the above approach #include <bits/stdc++.h> using namespace std;
// Function to find the length of // smallest substring of a having // string b as a subsequence int minLength(string a, string b)
{ // Stores the characters present
// in string b
map< char , int > Char;
for ( int i = 0; i < b.length(); i++) {
Char[b[i]]++;
}
// Find index of characters of a
// that are also present in string b
map< char , vector< int > > CharacterIndex;
for ( int i = 0; i < a.length(); i++) {
char x = a[i];
// If character is present in string b
if (Char.find(x) != Char.end()) {
// Store the index of character
CharacterIndex[x].push_back(i);
}
}
int len = INT_MAX;
// Flag is used to check if
// substring is possible
int flag;
while ( true ) {
// Assume that substring is
// possible
flag = 1;
// Stores first and last
// indices of the substring
// respectively
int firstVar, lastVar;
for ( int i = 0; i < b.length(); i++) {
// For first character of string b
if (i == 0) {
// If the first character of
// b is not present in a
if (CharacterIndex.find(b[i])
== CharacterIndex.end()) {
flag = 0;
break ;
}
// If the first character of b
// is present in a
else {
int x = *(
CharacterIndex[b[i]].begin());
// Remove the index from map
CharacterIndex[b[i]].erase(
CharacterIndex[b[i]].begin());
// Update indices of
// the substring
firstVar = x;
lastVar = x;
}
}
// For the remaining characters of b
else {
int elementFound = 0;
for ( auto e : CharacterIndex[b[i]]) {
if (e > lastVar) {
// If index possible for
// current character
elementFound = 1;
lastVar = e;
break ;
}
}
if (elementFound == 0) {
// If no index is possible
flag = 0;
break ;
}
}
}
if (flag == 0) {
// If no more substring
// is possible
break ;
}
// Update the minimum length
// of substring
len = min(len,
abs (lastVar - firstVar) + 1);
}
// Return the result
return len;
} // Driver Code int main()
{ // Given two string
string a = "abcdefababaef" ;
string b = "abf" ;
int len = minLength(a, b);
if (len != INT_MAX) {
cout << len << endl;
}
else {
cout << "Impossible" << endl;
}
} |
Java
// Java program to implement // the above approach import java.util.ArrayList;
import java.util.HashMap;
class GFG{
// Function to find the length of // smallest substring of a having // string b as a subsequence static int minLength(String a, String b)
{ // Stores the characters present
// in string b
HashMap<Character, Integer> Char = new HashMap<>();
for ( int i = 0 ; i < b.length(); i++)
{
Char.put(b.charAt(i),
Char.getOrDefault(b.charAt(i), 0 ) + 1 );
}
// Find index of characters of a
// that are also present in string b
HashMap<Character, ArrayList<Integer>>
CharacterIndex = new HashMap<>();
for ( int i = 0 ; i < a.length(); i++)
{
char x = a.charAt(i);
// If character is present in string b
if (Char.containsKey(x))
{
if (CharacterIndex.get(x) == null )
{
CharacterIndex.put(
x, new ArrayList<Integer>());
}
// Store the index of character
CharacterIndex.get(x).add(i);
}
}
int len = Integer.MAX_VALUE;
// Flag is used to check if
// substring is possible
int flag;
while ( true )
{
// Assume that substring is
// possible
flag = 1 ;
// Stores first and last
// indices of the substring
// respectively
int firstVar = 0 , lastVar = 0 ;
for ( int i = 0 ; i < b.length(); i++)
{
// For first character of string b
if (i == 0 )
{
// If the first character of
// b is not present in a
if (CharacterIndex.containsKey(i))
{
flag = 0 ;
break ;
}
// If the first character of b
// is present in a
else
{
int x = CharacterIndex.get(b.charAt(i)).get( 0 );
// Remove the index from map
CharacterIndex.get(b.charAt(i)).remove(
CharacterIndex.get(b.charAt(i)).get( 0 ));
// Update indices of
// the substring
firstVar = x;
lastVar = x;
}
}
// For the remaining characters of b
else
{
int elementFound = 0 ;
for (var e :
CharacterIndex.get(b.charAt(i)))
{
if (e > lastVar)
{
// If index possible for
// current character
elementFound = 1 ;
lastVar = e;
break ;
}
}
if (elementFound == 0 )
{
// If no index is possible
flag = 0 ;
break ;
}
}
}
if (flag == 0 )
{
// If no more substring
// is possible
break ;
}
// Update the minimum length
// of substring
len = Math.min(
len, Math.abs(lastVar - firstVar) + 1 );
}
// Return the result
return len;
} // Driver code public static void main(String[] args)
{ // Given two string
String a = "abcdefababaef" ;
String b = "abf" ;
int len = minLength(a, b);
if (len != Integer.MAX_VALUE)
{
System.out.println(len);
}
else
{
System.out.println( "Impossible" );
}
} } // This code is contributed by sk944795 |
Python3
# Python3 program to implement # the above approach import sys
# Function to find the length of # smallest substring of a having # string b as a subsequence def minLength(a, b):
# Stores the characters present
# in string b
Char = {}
for i in range ( len (b)):
Char[b[i]] = Char.get(b[i], 0 ) + 1
# Find index of characters of a
# that are also present in string b
CharacterIndex = {}
for i in range ( len (a)):
x = a[i]
# If character is present in string b
if (x in Char):
# Store the index of character
CharacterIndex[x] = CharacterIndex.get(x, [])
CharacterIndex[x].append(i)
l = sys.maxsize
# Flag is used to check if
# substring is possible
while ( True ):
# Assume that substring is
# possible
flag = 1
firstVar = 0
lastVar = 0
# Stores first and last
# indices of the substring
# respectively
for i in range ( len (b)):
# For first character of string b
if (i = = 0 ):
# If the first character of
# b is not present in a
if (b[i] not in CharacterIndex):
flag = 0
break
# If the first character of b
# is present in a
else :
x = CharacterIndex[b[i]][ 0 ]
# Remove the index from map
CharacterIndex[b[i]].remove(
CharacterIndex[b[i]][ 0 ])
# Update indices of
# the substring
firstVar = x
lastVar = x
# For the remaining characters of b
else :
elementFound = 0
for e in CharacterIndex[b[i]]:
if (e > lastVar):
# If index possible for
# current character
elementFound = 1
lastVar = e
break
if (elementFound = = 0 ):
# If no index is possible
flag = 0
break
if (flag = = 0 ):
# If no more substring
# is possible
break
# Update the minimum length
# of substring
l = min (l, abs (lastVar - firstVar) + 1 )
# Return the result
return l
# Driver Code if __name__ = = '__main__' :
# Given two string
a = "abcdefababaef"
b = "abf"
l = minLength(a, b)
if (l ! = sys.maxsize):
print (l)
else :
print ( "Impossible" )
# This code is contributed by SURENDRA_GANGWAR |
C#
// C# program to implement // the above approach using System;
using System.Collections.Generic;
class GFG
{ // Function to find the length of
// smallest substring of a having
// string b as a subsequence
static int MinLength( string a, string b)
{
// Stores the characters present
// in string b
Dictionary< char , int > Char
= new Dictionary< char , int >();
for ( int i = 0; i < b.Length; i++) {
if (Char.ContainsKey(b[i])) {
Char[b[i]] += 1;
}
else {
Char[b[i]] = 1;
}
}
// Find index of characters of a
// that are also present in string b
Dictionary< char , List< int > > CharacterIndex
= new Dictionary< char , List< int > >();
for ( int i = 0; i < a.Length; i++) {
char x = a[i];
// If character is present in string b
if (Char.ContainsKey(x)) {
if (!CharacterIndex.ContainsKey(x)) {
CharacterIndex[x] = new List< int >();
}
// Store the index of character
CharacterIndex[x].Add(i);
}
}
int len = int .MaxValue;
// Flag is used to check if
// substring is possible
bool flag;
while ( true ) {
// Assume that substring is
// possible
flag = true ;
// Stores first and last
// indices of the substring
// respectively
int firstVar = 0, lastVar = 0;
for ( int i = 0; i < b.Length; i++)
{
// For first character of string b
if (i == 0)
{
// If the first character of
// b is not present in a
if (!CharacterIndex.ContainsKey(b[i])) {
flag = false ;
break ;
}
// If the first character of b
// is present in a
else {
int x = CharacterIndex[b[i]][0];
// Remove the index from map
CharacterIndex[b[i]].RemoveAt(0);
// Update indices of
// the substring
firstVar = x;
lastVar = x;
}
}
// For the remaining characters of b
else {
bool elementFound = false ;
foreach ( int e in CharacterIndex[b[i]])
{
if (e > lastVar)
{
// If index possible for
// current character
elementFound = true ;
lastVar = e;
break ;
}
}
if (elementFound == false ) {
// If no index is possible
flag = false ;
break ;
}
}
}
if (flag == false ) {
// If no more substring
// is possible
break ;
}
// Update the minimum length
// of substring
len = Math.Min(len, Math.Abs(lastVar - firstVar)
+ 1);
}
// Return the result
return len;
}
static void Main( string [] args)
{
// Given two strings
string a = "abcdefababaef" ;
string b = "abf" ;
int len = MinLength(a, b);
if (len != int .MaxValue) {
Console.WriteLine(len);
}
else {
Console.WriteLine( "Impossible" );
}
}
} |
Javascript
// Javascript program to implement // the above approach // Function to find the length of // smallest substring of a having // string b as a subsequence function minLength(a, b) {
// Stores the characters present
// in string b
let Char = {};
for (let i = 0; i < b.length; i++) {
Char[b[i]] = (Char[b[i]] || 0) + 1;
}
// Find index of characters of a
// that are also present in string b
let CharacterIndex = {};
for (let i = 0; i < a.length; i++) {
let x = a[i];
// If character is present in string b
if (Char[x] !== undefined) {
if (CharacterIndex[x] === undefined) {
CharacterIndex[x] = [];
}
// Store the index of character
CharacterIndex[x].push(i);
}
}
let len = Number.MAX_VALUE;
// Flag is used to check if
// substring is possible
let flag;
while ( true ) {
// Assume that substring is
// possible
flag = 1;
// Stores first and last
// indices of the substring
// respectively
let firstVar = 0, lastVar = 0;
for (let i = 0; i < b.length; i++) {
// For first character of string b
if (i === 0) {
// If the first character of
// b is not present in a
if (!CharacterIndex[b[i]]) {
flag = 0;
break ;
}
// If the first character of b
// is present in a
else {
let x = CharacterIndex[b[i]][0];
// Remove the index from map
CharacterIndex[b[i]].splice(0, 1);
// Update indices of
// the substring
firstVar = x;
lastVar = x;
}
}
// For the remaining characters of b
else {
let elementFound = 0;
for (let e of CharacterIndex[b[i]]) {
if (e > lastVar) {
// If index possible for
// current character
elementFound = 1;
lastVar = e;
break ;
}
}
if (elementFound === 0) {
// If no index is possible
flag = 0;
break ;
}
}
}
if (flag === 0) {
// If no more substring
// is possible
break ;
}
// Update the minimum length
// of substring
len = Math.min(len, Math.abs(lastVar - firstVar) + 1);
}
// Return the result
return len;
} // Given two strings let a = "abcdefababaef" ;
let b = "abf" ;
let len = minLength(a, b); if (len !== Number.MAX_VALUE) {
console.log(len);
} else { console.log( "Impossible" );
} |
Output:
5
Time Complexity: O(N2)
Auxiliary Space: O(N), since N extra space has been taken.