Minimum Window Substring
1Try it yourself first
Think for 20-30 minutes before you open any hint. Being stuck is where the learning happens.
Only for you, saved in this browser. After you see the approach you will compare it with your idea.2What is being asked
Find the shortest part of s that contains every character of t (with counts).
3Hint ladder
Take one rung at a time. Stop as soon as the idea clicks.
- Hint 1Track how many required characters are still missing.
- Hint 2When nothing is missing, try to move the left edge in.
4The approach
Have you tried the hints? The approach is built as a path from the obvious way to the clever one.
Your shopping list says: bread, milk, eggs. A long street has shops in a row. Walk down the street collecting items until your list is complete, then try to shorten your walk from the back: if the first shop you passed was not needed (or you have a spare), drop it. Note the shortest stretch of street that ever had everything.
- The obvious way
Check every substring for coverage: O(n² x m).
- The key insight
Keep a tally of what the list still needs (it can go negative for surplus items) and a count of items still missing. Move the right edge: a needed item lowers the missing count. When nothing is missing the window is valid; move the left edge in as far as it stays valid (items with spares may leave) and record the shortest window. Then drop one needed item and keep looking. Every character enters and leaves at most once.
- The algorithm
- Tally the needs from t; missing = len(t).
- Walk the right edge: if the character is still needed, missing goes down by 1. Lower its tally by 1.
- Nothing missing? Slide the left edge in while the character leaving has a spare (tally below 0).
- Record the window if it is the shortest. Then drop one needed character and keep walking.
Watch it run
Examplestreet = "ADOBECODEBANC", list = "ABC"
Walk right until A, B and C have all been collected: "ADOBEC" (length 6).
best "ADOBEC"
Where people slip
- Duplicates in t matter: use counts, not a set.
- The tally goes negative for surplus characters; that is exactly how the shrink step knows what is spare.
How close was your idea?
You did not write an idea, and that is fine.
Be honest with yourself. This sets your revision list.
5Code
Try writing it yourself from the steps first. Then compare.
from collections import Counter
def min_window(s, t):
needs = Counter(t) # what the list still needs
missing = len(t)
left = 0
best_start, best_end = 0, float("inf")
for right, character in enumerate(s):
if needs[character] > 0:
missing -= 1 # a needed item collected
needs[character] -= 1
if missing == 0: # everything collected: shrink
while needs[s[left]] < 0: # spare items can leave
needs[s[left]] += 1
left += 1
if right - left < best_end - best_start:
best_start, best_end = left, right
needs[s[left]] += 1 # drop a needed item, search again
missing += 1
left += 1
return "" if best_end == float("inf") else s[best_start : best_end + 1]Now close this and write it again from memory, in the language you will use in the interview. Reattempt after 1 day, 7 days and about 30 days.
6Still stuck? Watch a video
Seeing someone explain it out loud can make it click. Try the video after you have read the approach above.