◀ THE GRIND — SLIDING WINDOW

Minimum Window Substring

The drill: Somewhere in string s hides the shortest stretch containing every character of t, duplicates included — find it, or report that nothing qualifies. The defining workout for expand-and-contract windows: counts decide when a window is legal, and legality lets the left edge chase the right.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

Two strings arrive, s and t. Somewhere inside s there may exist a contiguous stretch that contains every character of t, with duplicates matched at least as many times as they appear in t.

The job is to find the shortest such stretch and hand it back exactly as it appears in s. If no stretch of s covers every character of t, the answer is an empty string instead.

Order inside the window doesn't matter — only that the required character counts are all met simultaneously. Multiple windows can tie for shortest; any one of them is an acceptable answer.

EX 01
s = "xayzbca" · t = "abc"
"bca"
THE TIGHT WINDOW SITS AT THE TAIL
EX 02
s = "abaxab" · t = "aab"
"aba"
DUPLICATES IN T MUST ALL BE COVERED
EX 03
s = "aa" · t = "aaa"
""
T LONGER THAN S — IMPOSSIBLE
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

Checking every substring recounts the same letters thousands of times. A window that slides one step can inherit its own bookkeeping — what, exactly, needs to carry over?

HINT 2 THE STRUCTURE

March the right edge forward until the window covers t, then pull the left edge in while coverage survives. Both edges only ever move forward, so the sweep is linear.

HINT 3 ONE STEP FROM THE ANSWER

Keep per-character need counts plus one number, missing. The right edge decrements a need — missing drops only if that need was positive. The left edge increments it back — missing rises when a need turns positive. Snapshot the window every time missing is zero.

COACH'S BOARD — THE PATTERN, STEP BY STEP
EXPAND, THEN CHASE IT SHUTPATTERN · SLIDING WINDOW — VARIABLE WIDTHs = "xayzbca" · t = "abc"
x
a
y
z
b
c
a
NEED (a,b,c) · MISSING
— empty —
STEP 1

t = "abc" needs one each of a, b, c. Missing starts at 3 — expand right until missing hits 0, then contract left while it stays 0.

STEP 1 / 9 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/minimum-window-substring.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def minWindow(self, s: str, t: str) -> str:
        if len(t) > len(s):
            return ""
        need = collections.Counter(t)
        missing = len(t)          # required characters not yet inside the window
        best_lo, best_hi = 0, -1  # best window seen; hi < lo means none yet
        lo = 0
        for hi, c in enumerate(s):
            if need[c] > 0:
                missing -= 1
            need[c] -= 1
            while missing == 0:   # window is legal — contract from the left
                if best_hi < 0 or hi - lo < best_hi - best_lo:
                    best_lo, best_hi = lo, hi
                left = s[lo]
                need[left] += 1
                if need[left] > 0:  # that character just broke coverage
                    missing += 1
                lo += 1
        return s[best_lo:best_hi + 1]
TIME O(N + M)SPACE O(1)PYTHON · RACE PACE · 21 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED