PracticeNeetCode ↗LeetCode ↗
Given two strings s and t, return the smallest substring of s that contains every character of t (matching duplicate counts too). Return an empty string if no such substring exists.
t.t's distinct characters currently have their required count satisfied (formed), instead of comparing full count maps at every step.t, that's a candidate for the smallest answer — try shrinking before expanding again.need from t, and let required be the number of distinct characters in it.right over s, updating a window count map; when a character's window count first matches its need, increment formed.formed == required: record the window if it's the smallest seen so far, then shrink from the left — decrement the count for s[left], and if that drops below its need, decrement formed.right reaches the end of s.Time: O(|s| + |t|) — Space: O(|s| + |t|)
def minWindow(s: str, t: str) -> str:
if not s or not t:
return ""
need = {}
for ch in t:
need[ch] = need.get(ch, 0) + 1
required = len(need)
window = {}
formed = 0
left = 0
best_len = float('inf')
best_left = 0
for right, ch in enumerate(s):
window[ch] = window.get(ch, 0) + 1
if ch in need and window[ch] == need[ch]:
formed += 1
while formed == required:
if right - left + 1 < best_len:
best_len = right - left + 1
best_left = left
left_ch = s[left]
window[left_ch] -= 1
if left_ch in need and window[left_ch] < need[left_ch]:
formed -= 1
left += 1
return "" if best_len == float('inf') else s[best_left : best_left + best_len]How the solution above works, piece by piece.
need counts the letters of t; required is how many distinct letters must be satisfied.right. When a letter's window count reaches exactly its need, one more requirement is met (formed += 1).while formed == required: the window contains all of t. Record it if it's the shortest so far…s[left] drops a needed letter below its count, the window is no longer valid and growing resumes.Running it on s = "ADOBECODEBANC", t = "ABC":
while loop runs). The code keeps the shortest: "BANC", length 4.