Open In App

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

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:

Below is the implementation of the above approach:




// 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 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 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# 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 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.

 


Article Tags :