Smallest window in a String containing all characters of other String
Given two strings, string and pattern, the task is to find the smallest substring in string containing all characters of pattern.
Examples:
Input: string = “this is a test string”, pattern = “tist”
Output: “t stri”
Explanation: “t stri” contains all the characters of pattern.Input: string = “geeksforgeeks”, pattern = “ork”
Output: “ksfor”
Naive Approach:
- Generate all substrings of string.
- For each substring, check whether the substring contains all characters of pattern (“tist”)
- Finally, print the smallest substring containing all characters of pattern.
Time Complexity: O(N3)
Auxiliary Space: O(N) to create substrings.
Smallest window in a String containing all characters of other String using Hashing:
The idea is to use the two pointer approach on the hash array of pattern string and then find the minimum window by eliminating characters from the start of the window.
Follow the steps below to solve the problem:
- First check if the length of the string is less than the length of the given pattern, if yes then “no such window can exist “.
- Store the occurrence of characters of the given pattern in a hash array (say, hash_pat[]).
- We will be using two pointer technique basically
- Start matching the characters of the pattern with the characters of the string i.e. increment count if a character matches.
- Check if (count == length of pattern ) this means a window is found.
- If such a window is found, try to minimize it by removing extra characters from the beginning of the current window.
- Delete one character from the first and again find this deleted key at right.
- If found, then again check if count and pattern length are same and repeat the process.
- Update min_length.
- Print the minimum length window.
See the image below for a better understanding:
Illustration:

after the second image(array) our left pointer should be at s and then find I at right and then apply step5 (basically one step has not been shown)
Below is the implementation of the above approach.
C++
// 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 // Count of characters int count = 0; 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_str[str[j]] <= hash_pat[str[j]]) count++; // if all the characters are matched if (count == len2) { // Try to minimize the window 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 << findSubString(str, pat); return 0; } |
Java
// 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 // Count of characters int count = 0 ; 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_str[str.charAt(j)] <= hash_pat[str.charAt(j)]) count++; // If all the characters are matched if (count == len2) { // Try to minimize the window 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(findSubString(str, pat)); } } |
Python3
# 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_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 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 (findSubString(string, pat)) # This code is contributed by Rituraj Jain |
C#
// 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 // Count of characters int count = 0; 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_str[str[j]] <= hash_pat[str[j]]) count++; // if all the characters are matched if (count == len2) { // Try to minimize the window 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(findSubString(str, pat)); } } /* This code contributed by PrinciRaj1992 */ |
PHP
<?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_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 findSubString( $str , $pat ); // This code is contributed by // rathbhupendra ?> |
Javascript
<script> // javascript program to find smallest // window containing // all characters of a pattern. var no_of_chars = 256; // Function to find smallest // window containing // all characters of 'pat' function findSubString(str, pat) { var len1 = str.length; var 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) { document.write( "No such window exists" ); return "" ; } var hash_pat = Array.from({length: no_of_chars}, (_, i) => 0); var hash_str = Array.from({length: no_of_chars}, (_, i) => 0); // Store occurrence ofs // characters of pattern for ( var i = 0; i < len2; i++) hash_pat[pat.charAt(i).charCodeAt(0)]++; var start = 0, start_index = -1, min_len = Number.MAX_VALUE; // Start traversing the string // Count of characters var count = 0; for ( var j = 0; j < len1; j++) { // Count occurrence of characters // of string hash_str[str.charAt(j).charCodeAt(0)]++; // If string's char matches // with pattern's char // then increment count if (hash_str[str.charAt(j).charCodeAt(0)] <= hash_pat[str.charAt(j).charCodeAt(0)]) count++; // If all the characters are matched if (count == len2) { // Try to minimize the window while (hash_str[str.charAt(start).charCodeAt(0)] > hash_pat[str.charAt(start).charCodeAt(0)] || hash_pat[str.charAt(start).charCodeAt(0)] == 0) { if (hash_str[str.charAt(start).charCodeAt(0)] > hash_pat[str.charAt(start).charCodeAt(0)]) hash_str[str.charAt(start).charCodeAt(0)]--; start++; } // update window size var 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) { document.write( "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 var str = "this is a test string" ; var pat = "tist" ; document.write(findSubString(str, pat)); // This code is contributed by 29AjayKumar </script> |
t stri
Time Complexity: O(N), where N is the length of string.
Auxiliary Space: O(1)
BRUTE APPROACH USING HASH MAP:
Intuition:
- We create a HashMap<Character,Integer> to store frequency map of string p.
- Then we traverse through string s following the approach acquire and release.
- In this approach, first we declare two pointers i and j.
- i goes on the string s until we we all the desired characters required for p, and then j pointer eliminates all the unnecessary character since we require the minimum string.
- we store the result and compare with the upcoming results generated from the algorithm.
- Atlast we return the string.
Implementation:
C++
#include <iostream> #include <unordered_map> using namespace std; string smallestWindow(string s, string p) { if (s.empty() || p.empty()) { return "-1" ; } unordered_map< char , int > freq_map; // stores frequency of each character in pattern p for ( char c : p) { freq_map++; } int i = 0, j = 0, count = freq_map.size(); int left = 0, right = 0, min_len = s.length(); bool found = false ; while (j < s.length()) { char end_char = s[j++]; if (freq_map.count(end_char)) { freq_map[end_char]--; if (freq_map[end_char] == 0) { count--; } } // all characters of pattern p are found in current window if (count > 0) { continue ; } // shrink the window until all characters of pattern p are not present while (count == 0) { char start_char = s[i++]; if (freq_map.count(start_char)) { freq_map[start_char]++; if (freq_map[start_char] > 0) { count++; } } } // update the left and right indices if a smaller window is found if ((j - i) < min_len) { left = i - 1; right = j; min_len = j - i; found = true ; } } return found ? s.substr(left, right - left) : "-1" ; } int main() { string str = "this is a test string" ; string pat = "tist" ; cout << smallestWindow(str, pat) << endl; return 0; } // This code is contributed by Abahy_Mishra |
Java
// Java program to find smallest // window containing // all characters of a pattern. import java.io.*; import java.util.*; class GFG { public static String smallestWindow(String s, String p) { // Your code here if (s.isEmpty() || p.isEmpty()) return "-1" ; Map<Character, Integer> map = new HashMap<>(); for ( int i = 0 ; i < p.length(); i++) { char c = p.charAt(i); map.put(c, map.getOrDefault(c, 0 ) + 1 ); } int i = 0 , j = 0 , count = map.size(); int left = 0 , right = 0 , min = s.length(); boolean found = false ; while (j < s.length()) { char endchar = s.charAt(j++); if (map.containsKey(endchar)) { map.put(endchar, map.get(endchar) - 1 ); if (map.get(endchar) == 0 ) count -= 1 ; } if (count > 0 ) continue ; while (count == 0 ) { char strchar = s.charAt(i++); if (map.containsKey(strchar)) { map.put(strchar, map.get(strchar) + 1 ); if (map.get(strchar) > 0 ) count += 1 ; } } if ((j - i) < min) { left = i - 1 ; right = j; min = j - i; found = true ; } } return !found ? "-1" : s.substring(left, right); } public static void main(String[] args) { String str = "this is a test string" ; String pat = "tist" ; System.out.print(smallestWindow(str, pat)); } } // This code is contributed by Raunak Singh |
Python3
def smallestWindow(s, p): if not s or not p: return "-1" freq_map = {} # stores frequency of each character in pattern p for c in p: freq_map = freq_map.get(c, 0 ) + 1 i, j, count = 0 , 0 , len (freq_map) left, right, min_len = 0 , 0 , len (s) found = False while j < len (s): end_char = s[j] j + = 1 if end_char in freq_map: freq_map[end_char] - = 1 if freq_map[end_char] = = 0 : count - = 1 # all characters of pattern p are found in current window if count > 0 : continue # shrink the window until all characters of pattern p are not present while count = = 0 : start_char = s[i] i + = 1 if start_char in freq_map: freq_map[start_char] + = 1 if freq_map[start_char] > 0 : count + = 1 # update the left and right indices if a smaller window is found if (j - i) < min_len: left, right = i - 1 , j min_len = j - i found = True return s[left:right] if found else "-1" # Driver code str = "this is a test string" pat = "tist" print (smallestWindow( str , pat)) |
t stri
Time complexity: O(N),where N is the length of string s.
Space complexity: O(N),since we are using Hash Map for storing the characters.
Smallest window in a string containing all characters of other string using Sliding Window:
The idea is to use the sliding window technique whenever any window contains all the characters of the pattern string then start minimizing it from the start of the window.
Follow the steps below to solve the problem:
- Make a hash array of size 256.
- First store the frequency of every character of pattern string.
- Then loop over the string and decrement the frequency from the hash array.
- When count variable equals to zero then start minimizing the window.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h> using namespace std; // Function string Minimum_Window(string s, string t) { int m[256] = { 0 }; // Answer int ans = INT_MAX; // length of ans int start = 0; // starting index of ans int count = 0; // creating map for ( int i = 0; i < t.length(); i++) { if (m[t[i]] == 0) count++; m[t[i]]++; } // References of Window int i = 0; int j = 0; // Traversing the window while (j < s.length()) { // Calculations m[s[j]]--; if (m[s[j]] == 0) count--; // Condition matching if (count == 0) { while (count == 0) { // Sorting ans if (ans > j - i + 1) { ans = min(ans, j - i + 1); start = i; } // Sliding I // Calculation for removing I m[s[i]]++; if (m[s[i]] > 0) count++; i++; } } j++; } if (ans != INT_MAX) return s.substr(start, ans); else return "-1" ; } int main() { string s = "this is a test string" ; string t = "tist" ; cout << Minimum_Window(s, t); return 0; } |
Java
import java.util.*; class GFG { // Function static String Minimum_Window( char [] s, char [] t) { int m[] = new int [ 256 ]; // Answer int ans = Integer.MAX_VALUE; // length of ans int start = 0 ; // starting index of ans int count = 0 ; // creating map for ( int i = 0 ; i < t.length; i++) { if (m[t[i]] == 0 ) count++; m[t[i]]++; } // References of Window int i = 0 ; int j = 0 ; // Traversing the window while (j < s.length) { // Calculations m[s[j]]--; if (m[s[j]] == 0 ) count--; // Condition matching if (count == 0 ) { while (count == 0 ) { // Sorting ans if (ans > j - i + 1 ) { ans = Math.min(ans, j - i + 1 ); start = i; } // Sliding I // Calculation for removing I m[s[i]]++; if (m[s[i]] > 0 ) count++; i++; } } j++; } if (ans != Integer.MAX_VALUE) return String.valueOf(s).substring(start, ans + start); else return "-1" ; } public static void main(String[] args) { String s = "this is a test string" ; String t = "tist" ; System.out.print(Minimum_Window(s.toCharArray(), t.toCharArray())); } } // This code is contributed by 29AjayKumar |
Python3
''' Python solution ''' def smallestWindow(s, p): n = len (s) if n < len (p): return - 1 mp = [ 0 ] * 256 # Starting index of ans start = 0 # Answer # Length of ans ans = n + 1 cnt = 0 # creating map for i in p: mp[ ord (i)] + = 1 if mp[ ord (i)] = = 1 : cnt + = 1 # References of Window j = 0 i = 0 # Traversing the window while (j < n): # Calculating mp[ ord (s[j])] - = 1 if mp[ ord (s[j])] = = 0 : cnt - = 1 # Condition matching while cnt = = 0 : if ans > j - i + 1 : # calculating answer. ans = j - i + 1 start = i # Sliding I # Calculation for removing I mp[ ord (s[i])] + = 1 if mp[ ord (s[i])] > 0 : cnt + = 1 i + = 1 j + = 1 if ans > n: return "-1" return s[start:start + ans] # Driver code if __name__ = = "__main__" : s = "this is a test string" p = "tist" result = smallestWindow(s, p) print (result) # This code is contributed by cyclades. |
C#
using System; class GFG { // Function static String Minimum_Window( char [] s, char [] t) { int [] m = new int [256]; // Answer // Length of ans int ans = int .MaxValue; // Starting index of ans int start = 0; int count = 0, i = 0; // Creating map for (i = 0; i < t.Length; i++) { if (m[t[i]] == 0) count++; m[t[i]]++; } // References of Window i = 0; int j = 0; // Traversing the window while (j < s.Length) { // Calculations m[s[j]]--; if (m[s[j]] == 0) count--; // Condition matching if (count == 0) { while (count == 0) { // Sorting ans if (ans > j - i + 1) { ans = Math.Min(ans, j - i + 1); start = i; } // Sliding I // Calculation for removing I m[s[i]]++; if (m[s[i]] > 0) count++; i++; } } j++; } if (ans != int .MaxValue) return String.Join( "" , s).Substring(start, ans); else return "-1" ; } // Driver code public static void Main(String[] args) { String s = "this is a test string" ; String t = "tist" ; Console.Write(Minimum_Window(s.ToCharArray(), t.ToCharArray())); } } // This code is contributed by 29AjayKumar |
Javascript
<script> // Function function Minimum_Window(s,t) { let m = new Array(256); for (let i = 0; i < 256; i++) { m[i] = 0; } // Length of ans let ans = Number.MAX_VALUE; // Starting index of ans let start = 0; let count = 0; // Creating map for (let i = 0; i < t.length; i++) { if (m[t[i].charCodeAt(0)] == 0) count++; m[t[i].charCodeAt(0)]++; } // References of Window let i = 0; let j = 0; // Traversing the window while (j < s.length) { // Calculations m[s[j].charCodeAt(0)]--; if (m[s[j].charCodeAt(0)] == 0) count--; // Condition matching if (count == 0) { while (count == 0) { // Sorting ans if (ans > j - i + 1) { ans = Math.min(ans, j - i + 1); start = i; } // Sliding I // Calculation for removing I m[s[i].charCodeAt(0)]++; if (m[s[i].charCodeAt(0)] > 0) count++; i++; } } j++; } if (ans != Number.MAX_VALUE) return (s).join( "" ).substring( start, (start + ans)); else return "-1" ; } // Driver code let s = "this is a test string" ; let t = "tist" ; document.write(Minimum_Window( s.split( "" ), t.split( "" ))); // This code is contributed by rag2127 </script> |
t stri
Time Complexity: O(N), where N is the length of string s.
Auxiliary Space: O(1)
This article is contributed by Sahil Chhabra. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@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.
Please Login to comment...