Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Find the smallest window in a string containing all characters of another string in Python
Finding the smallest window in a string that contains all characters of another string is a classic sliding window problem. This technique uses two pointers to efficiently find the minimum substring.
Problem Statement
Given two strings s1 and s2, we need to find the smallest substring in s1 that contains all characters of s2.
For example, if s1 = "I am a student" and s2 = "mdn", the output should be "m a studen".
Algorithm Steps
The sliding window approach works as follows:
Create frequency arrays for both pattern and current window characters
Expand the window by moving the right pointer until all pattern characters are included
Contract the window from the left to find the minimum valid window
Keep track of the smallest valid window found
Implementation
def find_smallest_window(main_str, pattern):
N = 256 # ASCII character set size
str_len = len(main_str)
patt_len = len(pattern)
# If main string is smaller than pattern, no solution exists
if str_len < patt_len:
return None
# Frequency arrays for pattern and current window
pattern_freq = [0] * N
window_freq = [0] * N
# Count frequency of characters in pattern
for i in range(patt_len):
pattern_freq[ord(pattern[i])] += 1
start = 0
start_index = -1
min_len = float('inf')
count = 0 # Count of pattern characters matched
# Sliding window approach
for j in range(str_len):
# Add current character to window
window_freq[ord(main_str[j])] += 1
# If current character matches pattern requirement
if (pattern_freq[ord(main_str[j])] != 0 and
window_freq[ord(main_str[j])] <= pattern_freq[ord(main_str[j])]):
count += 1
# If all pattern characters are matched
if count == patt_len:
# Try to contract window from left
while (window_freq[ord(main_str[start])] > pattern_freq[ord(main_str[start])] or
pattern_freq[ord(main_str[start])] == 0):
if window_freq[ord(main_str[start])] > pattern_freq[ord(main_str[start])]:
window_freq[ord(main_str[start])] -= 1
start += 1
# Update minimum window if current is smaller
window_len = j - start + 1
if min_len > window_len:
min_len = window_len
start_index = start
# Return result
if start_index == -1:
return None
return main_str[start_index:start_index + min_len]
# Test the function
main_str = "I am a student"
pattern = "mdn"
result = find_smallest_window(main_str, pattern)
print(f"Smallest window: '{result}'")
Smallest window: 'm a studen'
How It Works
The algorithm uses a sliding window technique with two pointers:
Expand Phase: Move the right pointer to include more characters until all pattern characters are found
Contract Phase: Move the left pointer to remove unnecessary characters while maintaining validity
Update: Track the minimum valid window size and position
Another Example
# Test with different inputs
test_cases = [
("ADOBECODEBANC", "ABC"),
("hello world", "ell"),
("python", "hon")
]
for main_str, pattern in test_cases:
result = find_smallest_window(main_str, pattern)
print(f"String: '{main_str}', Pattern: '{pattern}' ? Result: '{result}'")
String: 'ADOBECODEBANC', Pattern: 'ABC' ? Result: 'BANC' String: 'hello world', Pattern: 'ell' ? Result: 'ell' String: 'python', Pattern: 'hon' ? Result: 'thon'
Time and Space Complexity
Time Complexity: O(n), where n is the length of the main string
Space Complexity: O(1), as we use fixed-size arrays of 256 elements
Conclusion
The sliding window approach efficiently finds the smallest substring containing all pattern characters in linear time. This technique is optimal for substring search problems with character frequency constraints.
