Optimal: need counts + satisfied counter
Time O(|s| + |t|) Space O(alphabet)need[c] from t; required = number of distinct letters in t. Grow right: increment have[c], and if it just reached need[c], increment formed. While formed == required, record the window if shortest, then remove s[left]: if its count drops below need, decrement formed; advance left.
s = "ADOBECODEBANC", t = "ABC"best(vars)
Step 1/4Grow until A, B and C are all inside: "ADOBEC" (length 6). Record it.
class Solution {
public String minWindow(String s, String t) {
int[] need = new int[128], have = new int[128];
int required = 0;
for (char c : t.toCharArray()) if (need[c]++ == 0) required++;
int formed = 0, left = 0, bestLen = Integer.MAX_VALUE, bestStart = 0;
for (int right = 0; right < s.length(); right++) {
char c = s.charAt(right);
if (++have[c] == need[c]) formed++;
while (formed == required) {
if (right - left + 1 < bestLen) {
bestLen = right - left + 1;
bestStart = left;
}
char out = s.charAt(left++);
if (have[out]-- == need[out]) formed--;
}
}
return bestLen == Integer.MAX_VALUE ? "" : s.substring(bestStart, bestStart + bestLen);
}
}Verdict: Each character of s enters and leaves the window once.