Two approaches to LeetCode Minimum Window Substring โ brute force O(nยฒ) and optimal sliding window O(n). Java and Python solutions with visual walkthrough.
LeetCode ยท #76
Minimum Window Substring Solution
Given strings s and t, return the minimum window in s that contains all characters of t.
Given two strings s and t of lengths m and n, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If no such window exists, return the empty string "".
Example
Input: s = "ADOBECODEBANC", t = "ABC"Output:"BANC"// "BANC" contains A, B, C. No shorter window does.
Example 2
Input: s = "a", t = "aa"Output:""// Need two 'a's but s has only one โ impossible
Constraints
โข 1 โค s.length, t.length โค 10โตโข s and t consist of uppercase and lowercase English letters
02
Section Two ยท Approach 1
Brute Force โ O(nยฒ ยท m)
Check every substring of s to see if it contains all characters of t. For each substring, build a frequency map and compare. Track the shortest valid one.
Problem: O(nยฒ) substrings, each costing O(m) to verify. A sliding window expands right to cover all characters, then shrinks left to minimize โ hitting each character at most twice for O(n + m) total.
Java โ Brute Force (TLE)
classSolution {
publicStringminWindow(String s, String t) {
String result = "";
for (int i = 0; i < s.length(); i++) {
for (int j = i + t.length(); j <= s.length(); j++) {
String sub = s.substring(i, j);
if (containsAll(sub, t))
if (result.isEmpty() || sub.length() < result.length())
result = sub;
}
}
return result;
}
// helper to check if sub contains all chars of tprivatebooleancontainsAll(String sub, String t) {
int[] count = newint[128];
for (char c : sub.toCharArray()) count[c]++;
for (char c : t.toCharArray()) if (--count[c] < 0) returnfalse;
returntrue;
}
}
Python โ Brute Force (TLE)
from collections importCounterclassSolution:
defminWindow(self, s: str, t: str) -> str:
t_count = Counter(t)
result = ""for i in range(len(s)):
for j in range(i + len(t), len(s) + 1):
if not (t_count - Counter(s[i:j])):
if not result or j - i < len(result):
result = s[i:j]
return result
Metric
Value
Time
O(nยฒ ยท m)
Space
O(m)
03
Section Three ยท Approach 2
Sliding Window โ O(n + m)
Two phases that repeat: expand the right pointer until the window contains all characters of t, then shrink the left pointer to find the minimum valid window. Track when all required characters are satisfied using a formed counter.
๐ก Mental model: Imagine you're casting a fishing net (the window) in a river of characters. First, you widen the net rightward until you've caught all the required fish (characters of t). Then you tighten the left side to use the smallest possible net โ as soon as a required fish escapes, you stop tightening and expand right again. You record the smallest net size that ever held all targets.
Algorithm
Step 1: Build tCount โ frequency map of t. Let required = number of unique characters in t.
Step 2: Maintain windowCount for the current window and formed = how many unique chars in t are fully satisfied.
Step 3: Expand right: add s[right] to windowCount. If windowCount[c] == tCount[c], increment formed.
Step 4: While formed == required: record window if smaller than best, then shrink left โ decrement windowCount[s[left]], if it drops below tCount, decrement formed. left++.
๐ฏ Key insight โ formed counter:
Instead of comparing entire frequency maps each step (O(52)), we track how many of t's unique characters are fully satisfied.
When a character's window count reaches its required count, formed++.
When it drops below, formed--. Checking formed == required is O(1).
04
Section Four ยท Trace
Visual Walkthrough
Trace through s = "ADOBECODEBANC", t = "ABC":
Expand right to cover, shrink left to minimize
05
Section Five ยท Implementation
Code โ Java & Python
Java โ Sliding Window
import java.util.HashMap;
classSolution {
publicStringminWindow(String s, String t) {
if (t.length() > s.length()) return"";
HashMap<Character, Integer> tCount = newHashMap<>();
for (char c : t.toCharArray()) tCount.merge(c, 1, Integer::sum);
int required = tCount.size();
int formed = 0;
HashMap<Character, Integer> window = newHashMap<>();
int left = 0, minLen = Integer.MAX_VALUE, minStart = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
window.merge(c, 1, Integer::sum);
if (tCount.containsKey(c) && window.get(c).intValue() == tCount.get(c).intValue())
formed++;
while (formed == required) {
if (right - left + 1 < minLen) {
minLen = right - left + 1;
minStart = left;
}
char leftChar = s.charAt(left);
window.put(leftChar, window.get(leftChar) - 1);
if (tCount.containsKey(leftChar) &&
window.get(leftChar) < tCount.get(leftChar))
formed--;
left++;
}
}
return minLen == Integer.MAX_VALUE ? "" : s.substring(minStart, minStart + minLen);
}
}
Python โ Sliding Window
from collections importCounterclassSolution:
defminWindow(self, s: str, t: str) -> str:
if len(t) > len(s): return""
t_count = Counter(t)
required = len(t_count)
formed = 0
window = {}
left = 0
min_len = float('inf')
min_start = 0for right in range(len(s)):
c = s[right]
window[c] = window.get(c, 0) + 1if c in t_count and window[c] == t_count[c]:
formed += 1while formed == required:
if right - left + 1 < min_len:
min_len = right - left + 1
min_start = left
window[s[left]] -= 1if s[left] in t_count and window[s[left]] < t_count[s[left]]:
formed -= 1
left += 1return""if min_len == float('inf') else s[min_start:min_start + min_len]
06
Section Six ยท Analysis
Complexity Analysis
Approach
Time
Space
Trade-off
Brute Force
O(nยฒ ยท m)
O(m)
Check all substrings
Sliding Window โ optimal
O(n + m)
O(m)
Each char enters/leaves window once. O(m) for t's freq map.
07
Section Seven ยท Edge Cases
Edge Cases & Pitfalls
Case
Input
Why It Matters
t longer than s
s="a", t="aa"
Impossible โ return "".
Exact match
s="abc", t="abc"
The entire string is the minimum window.
Duplicate chars in t
s="aa", t="aa"
Need two a's. Window count must meet the required count for each char.
Single char
s="abcda", t="a"
Minimum window is "a" at index 0 (or 4). Length 1.
No valid window
s="abc", t="d"
Character d doesn't exist in s โ "".
Case sensitive
s="Aa", t="a"
'A' โ 'a'. Only index 1 matches. Use int[128] for ASCII.
โ Common Mistake: Using == to compare Integer objects in Java. window.get(c) == tCount.get(c) compares references, not values, for integers outside the cached range [-128, 127]. Use .intValue() or .equals() to compare correctly.