Length of smallest substring of a given string which contains another string as subsequence

• Difficulty Level : Medium
• Last Updated : 20 May, 2021

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:
1. If found to be true, then initialize two variables firstVar and lastVar with the index of the first occurrence of B in the string A.
2. After updating the values, remove that character from the Map CharacterIndex.
3. 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 using namespace std; // Function to find the length of// smallest substring of a having// string b as a subsequenceint minLength(string a, string b){     // Stores the characters present    // in string b    map 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 > 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 Codeint 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 approachimport java.util.ArrayList;import java.util.HashMap; class GFG{ // Function to find the length of// smallest substring of a having// string b as a subsequencestatic int minLength(String a, String b){         // Stores the characters present    // in string b    HashMap 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>        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());            }                         // 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 codepublic 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 approachimport sys # Function to find the length of# smallest substring of a having# string b as a subsequencedef 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]]                     # Remove the index from map                    CharacterIndex[b[i]].remove(                    CharacterIndex[b[i]])                     # 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 Codeif __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
Output:
5

Time Complexity: O(N2)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up