Minimum Window Substring
Master this topic with zero to advance depth.
Minimum Window Substring
Given two strings s and t, return the minimum window substring of s such that every character in t (including duplicates) is included in the window.
Visual Representation
s = "ADOBECODEBANC", t = "ABC"
Window Expand (Found all ABC):
[ADOBEC]ODEBANC (Len: 6)
Window Shrink (Still have ABC):
A [DOBEC]ODEBANC (Len: 5) -> [DOBEC] (Wait, missing A!)
Final Optimal Window:
ADOBECODE [BANC] (Len: 4)Examples
Level I: Brute Force
Intuition
Check every possible substring of s and verify if it contains all characters of t in the required frequencies. Keep track of the minimum length substring that satisfies this.
Thought Process
- Iterate through all possible
startandendindices to define every substring. - For each substring, count its character frequencies.
- Compare these frequencies with the target frequency map of
t. - If the substring is valid, update the
minWindowresult.
Detailed Dry Run
| Substring | Valid? | Min Length | Min Window |
|---|---|---|---|
| "ADOBE" | No (missing C) | inf | "" |
| "ADOBEC" | YES! | 6 | "ADOBEC" |
| "BANC" | YES! | 4 | "BANC" |
Level II: Binary Search on Window Size
Intuition
The shortest valid window length must be between len(t) and len(s). We can binary search for this length k. For each k, we use a fixed-size sliding window of length k to check if any valid substring exists. If it does, we try smaller lengths; otherwise, we try larger ones.
Detailed Dry Run
Input: s = "ADOBECODEBANC", t = "ABC"
- Binary Search range:
[3, 13]. - Try
k = 8: SubstringADOBECODis valid. Search[3, 7]. - Try
k = 5: SubstringEBANCis valid. Search[3, 4]. - Try
k = 4: SubstringBANCis valid. Search[3, 3]. - Try
k = 3: No window of size 3 is valid. - Result:
k = 4, returnBANC.
Level III: Optimal (Sliding Window)
Intuition
Categorization
This is a Variable Size Window problem. We need to find the smallest range [L, R] that satisfies the requirement.
Thought Process
- Use a map
targetCountsto store required characters int. - Expand
rightuntil the window contains all characters int. We use ahavecounter vs aneedcounter for validity check. - Once valid, shrink
leftas much as possible while maintaining validity to find the smallest window. - Update the
minWindowresult whenever a smaller valid window is found.
Mandatory Variables
left,right: Window pointers.targetMap: Frequencies of characters int.windowMap: Frequencies of characters in the current window.have,need: Variables to track progress toward the target frequency.
Detailed Dry Run
s = "ADOBEC", t = "ABC"
| Step | L | R | Char | Window Map | Have/Need | Action |
|---|---|---|---|---|---|---|
| 1 | 0 | 0 | 'A' | {A:1} | 1/3 | Expand |
| 2-4 | 0 | 4 | 'E' | {A:1, B:1} | 2/3 | Expand |
| 5 | 0 | 5 | 'C' | {A:1, B:1, C:1} | 3/3 | VALID! |
| 6 | 1 | 5 | 'D' | {B:1, C:1} | 2/3 | Shrink (Invalidated) |
⚠️ Common Pitfalls & Tips
Be careful with character counts if t has duplicates. Using a have/need counter for unique characters is more robust than a total character count.
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.