Minimum Window Substring
Given two strings stst
Example 1
Output: "BANC"
Example 2
Output: "a"
Example 3
Output: ""
Explanation: t needs two a's, but s has only one.
How to Think About It
Step 1: When does a window "cover" t?
A window covers tt
: how many more copies ofneed[c] the window still needs. It starts as the count ofc inc , and can go negative when the window has extras.t : how many characters ofmissing are still not covered, counting repeats. The window coverst exactly whent .missing == 0
Step 2: Grow until the window covers t
Add s[right]needneedmissingneedmissing
Step 3: Shrink while it still covers t
While missing == 0
- record the window if it is the shortest so far;
- remove
: increase itss[left] . If that makesneed positive, a needed character just left, soneed goes up and the window no longer coversmissing ;t - move
forward.left
Step 4: Why this finds the shortest
For each right
Walkthrough
s = "ADOBECODEBANC"t = "ABC"
| right reaches | Covering window found | Length | What happens next |
|---|---|---|---|
| 5 (C) | ADOBEC | 6 | removing A uncovers it; grow again |
| 10 (A) | DOBECODEBA → shrink to CODEBA | 6 | not shorter; removing C uncovers it |
| 12 (C) | ODEBANC → shrink to EBANC | 5 | shorter: recorded |
| 12 (C) | BANC | 4 | shorter: recorded; removing B uncovers it |
The answer is "BANC".
Java Solution
One array, needmissing
public class MinimumWindowSubstring {
public static String minWindow(String s, String t) {
int[] need = new int[128]; // how many more of each character the window needs
for (char c : t.toCharArray()) {
need[c]++;
}
int missing = t.length(); // characters of t not yet covered
int left = 0;
int bestStart = 0;
int bestLen = Integer.MAX_VALUE;
for (int right = 0; right < s.length(); right++) {
if (need[s.charAt(right)]-- > 0) {
missing--; // this character was still needed
}
while (missing == 0) { // the window covers t: try to shrink it
if (right - left + 1 < bestLen) {
bestLen = right - left + 1;
bestStart = left;
}
if (++need[s.charAt(left)] > 0) {
missing++; // removing it uncovers a needed character
}
left++;
}
}
return bestLen == Integer.MAX_VALUE ? "" : s.substring(bestStart, bestStart + bestLen);
}
public static void main(String[] args) {
System.out.println(minWindow("ADOBECODEBANC", "ABC")); // BANC
System.out.println(minWindow("a", "a")); // a
System.out.println("[" + minWindow("a", "aa") + "]"); // []
}
}
The original implementation,
Complexity
- Time: O(m + n): each character of
enters and leaves the window once, plus one pass overs .t - Space: O(1): a fixed array of 128 counts.
When the window must have exactly the letters of t