from collections import Counter
class Solution:
def minWindow(self, s: str, t: str) -> str:
if not t or not s:
return ""
dict_t = Counter(t) # count chars needed
required = len(dict_t) # unique chars needed
l, r = 0, 0 # window pointers
formed = 0 # how many unique chars in current window match required count
window_counts = {}
ans = float('inf'), None, None # window length, left, right
while r < len(s):
character = s[r]
window_counts[character] = window_counts.get(character, 0) + 1
if character in dict_t and window_counts[character] == dict_t[character]:
formed += 1 # one required char count matched
while l <= r and formed == required:
character = s[l]
# update answer if smaller window found
if r - l + 1 < ans[0]:
ans = (r - l + 1, l, r)
window_counts[character] -= 1
if character in dict_t and window_counts[character] < dict_t[character]:
formed -= 1 # lost a required char count
l += 1 # shrink window from left
r += 1 # expand window from right
return "" if ans[0] == float('inf') else s[ans[1]:ans[2]+1]
# Driver code
s = "ADOBECODEBANC"
t = "ABC"
sol = Solution()
print(sol.minWindow(s, t))dict_t = Counter(t) # count chars needed
count how many of each character we need
required = len(dict_t) # unique chars needed
number of unique characters to match
expand window by moving right pointer
window_counts[character] = window_counts.get(character, 0) + 1
add current character to window count
if character in dict_t and window_counts[character] == dict_t[character]:
formed += 1
increment formed when a required char count is met
while l <= r and formed == required:
try to shrink window from left while all required chars are present
if r - l + 1 < ans[0]:
ans = (r - l + 1, l, r)
update smallest window found
window_counts[character] -= 1
if character in dict_t and window_counts[character] < dict_t[character]:
formed -= 1
reduce count of left char and update formed if needed