|
| 1 | +""" |
| 2 | +76. Minimum Window Substring |
| 3 | +
|
| 4 | +https://leetcode.com/problems/minimum-window-substring |
| 5 | +
|
| 6 | +NOTES |
| 7 | + * Use a sliding window. |
| 8 | +
|
| 9 | +Not sure why this is categorized as "hard". Maybe I've just done so many of |
| 10 | +these problems, the solution is intuitive. Frequency map, sliding window, boom, |
| 11 | +done. |
| 12 | +
|
| 13 | +Spoke too soon... Spent over thirty minutes with the tricky logic around |
| 14 | +remaining characters. The key is to only decrement/increment `remaining` if the |
| 15 | +count is greater than 0. This ensures the substring possesses all required |
| 16 | +characters without erroneously counting extra occurrences of characters already |
| 17 | +satisfied in the substring. |
| 18 | +""" |
| 19 | + |
| 20 | +import sys |
| 21 | +from collections import Counter |
| 22 | + |
| 23 | + |
| 24 | +class Solution: |
| 25 | + def minWindow(self, s: str, t: str) -> str: |
| 26 | + left, right, start, end, minimum_size = 0, 0, 0, 0, sys.maxsize |
| 27 | + |
| 28 | + # Create a frequency map. Additionally, keep track of the count of |
| 29 | + # remaining characters needed for the substring to be valid (i.e., |
| 30 | + # every character in `t` is included in the substring). |
| 31 | + counter: Counter[str] = Counter(t) |
| 32 | + remaining = len(t) |
| 33 | + |
| 34 | + while right < len(s): |
| 35 | + if s[right] in counter: |
| 36 | + # Only decrement `remaining` if count is greater than 0. |
| 37 | + if counter[s[right]] > 0: |
| 38 | + remaining -= 1 |
| 39 | + counter[s[right]] -= 1 |
| 40 | + while left <= right and remaining == 0: |
| 41 | + current_size = right - left + 1 |
| 42 | + if current_size < minimum_size: |
| 43 | + minimum_size = current_size |
| 44 | + start, end = left, right |
| 45 | + if s[left] in counter: |
| 46 | + counter[s[left]] += 1 |
| 47 | + # Only increment `remaining` if count is greater than 0. |
| 48 | + if counter[s[left]] > 0: |
| 49 | + remaining += 1 |
| 50 | + left += 1 |
| 51 | + right += 1 |
| 52 | + |
| 53 | + return s[start:end + 1] if minimum_size < sys.maxsize else "" |
0 commit comments