Find the smallest window in a string containing all characters of another string

Given two strings string1 and string2, the task is to find the smallest substring in string1 containing all characters of string2 efficiently.

Examples:

Input: string = “this is a test string”, pattern = “tist”
Output: Minimum window is “t stri”
Explanation: “t stri” contains all the characters of pattern.

Input: string = “geeksforgeeks”, pattern = “ork”
Output: Minimum window is “ksfor”

Method 1 ( Brute force solution )
1- Generate all substrings of string1 (“this is a test string”)
2- For each substring, check whether the substring contains all characters of string2 (“tist”)
3- Finally, print the smallest substring containing all characters of string2.

 
Method 2 ( Efficient Solution )

  1. First check if the length of string is less than the length of the given pattern, if yes then “no such window can exist “.
  2. Store the occurrence of characters of the given pattern in a hash_pat[].
  3. Start matching the characters of pattern with the characters of string i.e. increment count if a character matches.
  4. Check if (count == length of pattern ) this means a window is found.
  5. If such window found, try to minimize it by removing extra characters from the beginning of the current window.
  6. Update min_length.
  7. Print the minimum length window.

Diagram to explain the above algorithm:
smallest-window

Below is the program to implement the above algorithm:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find smallest window containing
// all characters of a pattern.
#include<bits/stdc++.h>
using namespace std;
  
const int no_of_chars = 256;
  
// Function to find smallest window containing
// all characters of 'pat'
string findSubString(string str, string pat)
{
    int len1 = str.length();
    int len2 = pat.length();
  
    // check if string's length is less than pattern's
    // length. If yes then no such window can exist
    if (len1 < len2)
    {
        cout << "No such window exists";
        return "";
    }
  
    int hash_pat[no_of_chars] = {0};
    int hash_str[no_of_chars] = {0};
  
    // store occurrence ofs characters of pattern
    for (int i = 0; i < len2; i++)
        hash_pat[pat[i]]++;
  
    int start = 0, start_index = -1, min_len = INT_MAX;
  
    // start traversing the string
    int count = 0; // count of characters
    for (int j = 0; j < len1 ; j++)
    {
        // count occurrence of characters of string
        hash_str[str[j]]++;
  
        // If string's char matches with pattern's char
        // then increment count
        if (hash_pat[str[j]] != 0 &&
            hash_str[str[j]] <= hash_pat[str[j]] )
            count++;
  
        // if all the characters are matched
        if (count == len2)
        {
            // Try to minimize the window i.e., check if
            // any character is occurring more no. of times
            // than its occurrence in pattern, if yes
            // then remove it from starting and also remove
            // the useless characters.
            while ( hash_str[str[start]] > hash_pat[str[start]]
                || hash_pat[str[start]] == 0)
            {
  
                if (hash_str[str[start]] > hash_pat[str[start]])
                    hash_str[str[start]]--;
                start++;
            }
  
            // update window size
            int len_window = j - start + 1;
            if (min_len > len_window)
            {
                min_len = len_window;
                start_index = start;
            }
        }
    }
  
    // If no window found
    if (start_index == -1)
    {
    cout << "No such window exists";
    return "";
    }
  
    // Return substring starting from start_index
    // and length min_len
    return str.substr(start_index, min_len);
}
  
// Driver code
int main()
{
    string str = "this is a test string";
    string pat = "tist";
  
    cout << "Smallest window is : \n"
        << findSubString(str, pat);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find smallest window containing
// all characters of a pattern.
  
public class GFG 
{
    static final int no_of_chars = 256;
      
    // Function to find smallest window containing
    // all characters of 'pat'
    static String findSubString(String str, String pat)
    {
        int len1 = str.length();
        int len2 = pat.length();
      
        // check if string's length is less than pattern's
        // length. If yes then no such window can exist
        if (len1 < len2)
        {
            System.out.println("No such window exists");
            return "";
        }
      
        int hash_pat[] = new int[no_of_chars];
        int hash_str[] = new int[no_of_chars];
      
        // store occurrence ofs characters of pattern
        for (int i = 0; i < len2; i++)
            hash_pat[pat.charAt(i)]++;
      
        int start = 0, start_index = -1, min_len = Integer.MAX_VALUE;
      
        // start traversing the string
        int count = 0; // count of characters
        for (int j = 0; j < len1 ; j++)
        {
            // count occurrence of characters of string
            hash_str[str.charAt(j)]++;
      
            // If string's char matches with pattern's char
            // then increment count
            if (hash_pat[str.charAt(j)] != 0 &&
                hash_str[str.charAt(j)] <= hash_pat[str.charAt(j)] )
                count++;
      
            // if all the characters are matched
            if (count == len2)
            {
                // Try to minimize the window i.e., check if
                // any character is occurring more no. of times
                // than its occurrence in pattern, if yes
                // then remove it from starting and also remove
                // the useless characters.
                while ( hash_str[str.charAt(start)] > hash_pat[str.charAt(start)]
                    || hash_pat[str.charAt(start)] == 0)
                {
      
                    if (hash_str[str.charAt(start)] > hash_pat[str.charAt(start)])
                        hash_str[str.charAt(start)]--;
                    start++;
                }
      
                // update window size
                int len_window = j - start + 1;
                if (min_len > len_window)
                {
                    min_len = len_window;
                    start_index = start;
                }
            }
        }
      
        // If no window found
        if (start_index == -1)
        {
        System.out.println("No such window exists");
        return "";
        }
      
        // Return substring starting from start_index
        // and length min_len
        return str.substring(start_index, start_index + min_len);
    }
      
    // Driver Method
    public static void main(String[] args)
    {
        String str = "this is a test string";
        String pat = "tist";
      
    System.out.print("Smallest window is :\n " +
                        findSubString(str, pat));
    }
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the smallest window 
# containing all characters of a pattern. 
no_of_chars = 256
  
# Function to find smallest window 
# containing all characters of 'pat' 
def findSubString(string, pat): 
  
    len1 = len(string) 
    len2 = len(pat) 
  
    # check if string's length is less than pattern's 
    # length. If yes then no such window can exist 
    if len1 < len2: 
      
        print("No such window exists"
        return "" 
  
    hash_pat = [0] * no_of_chars
    hash_str = [0] * no_of_chars 
  
    # store occurrence ofs characters of pattern 
    for i in range(0, len2): 
        hash_pat[ord(pat[i])] += 1
  
    start, start_index, min_len = 0, -1, float('inf'
  
    # start traversing the string 
    count = 0 # count of characters 
    for j in range(0, len1): 
      
        # count occurrence of characters of string 
        hash_str[ord(string[j])] += 1
  
        # If string's char matches with 
        # pattern's char then increment count 
        if (hash_pat[ord(string[j])] != 0 and
            hash_str[ord(string[j])] <= 
            hash_pat[ord(string[j])]): 
            count += 1
  
        # if all the characters are matched 
        if count == len2: 
          
            # Try to minimize the window i.e., check if 
            # any character is occurring more no. of times 
            # than its occurrence in pattern, if yes 
            # then remove it from starting and also remove 
            # the useless characters. 
            while (hash_str[ord(string[start])] > 
                   hash_pat[ord(string[start])] or
                   hash_pat[ord(string[start])] == 0): 
              
                if (hash_str[ord(string[start])] > 
                    hash_pat[ord(string[start])]): 
                    hash_str[ord(string[start])] -= 1
                start += 1
              
            # update window size 
            len_window = j - start + 1
            if min_len > len_window: 
              
                min_len = len_window 
                start_index = start 
  
    # If no window found 
    if start_index == -1:
        print("No such window exists"
        return "" 
      
    # Return substring starting from 
    # start_index and length min_len 
    return string[start_index : start_index + min_len] 
  
# Driver code 
if __name__ == "__main__":
  
    string = "this is a test string"
    pat = "tist"
  
    print("Smallest window is : ")
    print(findSubString(string, pat)) 
      
# This code is contributed by Rituraj Jain

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find smallest window containing
// all characters of a pattern.
using System;
  
class GFG 
{
    static int no_of_chars = 256;
      
    // Function to find smallest window containing
    // all characters of 'pat'
    static String findSubString(String str, String pat)
    {
        int len1 = str.Length;
        int len2 = pat.Length;
      
        // check if string's length is less than pattern's
        // length. If yes then no such window can exist
        if (len1 < len2)
        {
            Console.WriteLine("No such window exists");
            return "";
        }
      
        int []hash_pat = new int[no_of_chars];
        int []hash_str = new int[no_of_chars];
      
        // store occurrence ofs characters of pattern
        for (int i = 0; i < len2; i++)
            hash_pat[pat[i]]++;
      
        int start = 0, start_index = -1, min_len = int.MaxValue;
      
        // start traversing the string
        int count = 0; // count of characters
        for (int j = 0; j < len1 ; j++)
        {
            // count occurrence of characters of string
            hash_str[str[j]]++;
      
            // If string's char matches with pattern's char
            // then increment count
            if (hash_pat[str[j]] != 0 &&
                hash_str[str[j]] <= hash_pat[str[j]] )
                count++;
      
            // if all the characters are matched
            if (count == len2)
            {
                // Try to minimize the window i.e., check if
                // any character is occurring more no. of times
                // than its occurrence in pattern, if yes
                // then remove it from starting and also remove
                // the useless characters.
                while ( hash_str[str[start]] > hash_pat[str[start]]
                    || hash_pat[str[start]] == 0)
                {
      
                    if (hash_str[str[start]] > hash_pat[str[start]])
                        hash_str[str[start]]--;
                    start++;
                }
      
                // update window size
                int len_window = j - start + 1;
                if (min_len > len_window)
                {
                    min_len = len_window;
                    start_index = start;
                }
            }
        }
      
        // If no window found
        if (start_index == -1)
        {
            Console.WriteLine("No such window exists");
            return "";
        }
      
        // Return substring starting from start_index
        // and length min_len
        return str.Substring(start_index, min_len);
    }
      
    // Driver Method
    public static void Main(String[] args)
    {
        String str = "this is a test string";
        String pat = "tist";
      
        Console.WriteLine("Smallest window is :\n " +
                        findSubString(str, pat));
    }
}
  
/* This code contributed by PrinciRaj1992 */

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP program to find smallest window 
// containing all characters of a pattern. 
  
define("no_of_chars", 256); 
  
// Function to find smallest window 
// containing all characters of 'pat' 
function findSubString(&$str, &$pat
    $len1 = strlen($str); 
    $len2 = strlen($pat); 
  
    // check if string's length is less 
    // than pattern's length. If yes
    // then no such window can exist 
    if ($len1 < $len2
    
        echo "No such window exists"
        return ""
    
  
    $hash_pat = array_fill(0, no_of_chars, 0); 
    $hash_str = array_fill(0, no_of_chars, 0); 
  
    // store occurrence ofs characters
    // of pattern 
    for ($i = 0; $i < $len2; $i++) 
        $hash_pat[ord($pat[$i])]++; 
  
    $start = 0;
    $start_index = -1;
    $min_len = PHP_INT_MAX; 
  
    // start traversing the string 
    $count = 0; // count of characters 
    for ($j = 0; $j < $len1 ; $j++) 
    
        // count occurrence of characters
        // of string 
        $hash_str[ord($str[$j])]++; 
  
        // If string's char matches with 
        // pattern's char then increment count 
        if ($hash_pat[ord($str[$j])] != 0 && 
            $hash_str[ord($str[$j])] <=
            $hash_pat[ord($str[$j])]) 
            $count++; 
  
        // if all the characters are matched 
        if ($count == $len2
        
            // Try to minimize the window i.e., 
            // check if any character is occurring 
            // more no. of times than its occurrence 
            // in pattern, if yes then remove it from
            // starting and also remove the useless 
            // characters. 
            while ($hash_str[ord($str[$start])] > 
                   $hash_pat[ord($str[$start])] || 
                   $hash_pat[ord($str[$start])] == 0) 
            
  
                if ($hash_str[ord($str[$start])] >
                    $hash_pat[ord($str[$start])]) 
                    $hash_str[ord($str[$start])]--; 
                $start++; 
            
  
            // update window size 
            $len_window = $j - $start + 1; 
            if ($min_len > $len_window
            
                $min_len = $len_window
                $start_index = $start
            
        
    
  
    // If no window found 
    if ($start_index == -1) 
    
        echo "No such window exists"
        return ""
    
  
    // Return substring starting from 
    // start_index and length min_len 
    return substr($str, $start_index, $min_len); 
  
// Driver code 
$str = "this is a test string"
$pat = "tist"
  
echo "Smallest window is : \n" .
      findSubString($str, $pat); 
        
// This code is contributed by
// rathbhupendra
?>

chevron_right



Output:

Smallest window is : 
t stri

This article is contributed by Sahil Chhabra. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up