Skip to content

Commit b114299

Browse files
Add 'Minimum Window Substring'
1 parent e51eea7 commit b114299

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ A collection of LeetCode solutions
6464

6565
[Minimum Size Subarray Sum](./src/minimum_size_subarray_sum.py)
6666

67+
[Minimum Window Substring](./src/minimum_window_substring.py)
68+
6769
[Permutation in String](./src/permutation_in_string.py)
6870

6971
[Product of Array Except Self](./src/product_of_array_except_self.py)

src/minimum_window_substring.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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 ""
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""
2+
76. Minimum Window Substring
3+
4+
https://leetcode.com/problems/minimum-window-substring
5+
"""
6+
7+
from unittest import TestCase
8+
9+
from src.minimum_window_substring import Solution
10+
11+
12+
class TestSolution(TestCase):
13+
def test_1(self):
14+
exp = "BANC"
15+
assert Solution().minWindow("ADOBECODEBANC", "ABC") == exp
16+
17+
def test_2(self):
18+
exp = "a"
19+
assert Solution().minWindow("a", "a") == exp
20+
21+
def test_3(self):
22+
exp = ""
23+
assert Solution().minWindow("a", "aa") == exp
24+
25+
def test_4(self):
26+
exp = "ba"
27+
assert Solution().minWindow("bba", "ab") == exp

0 commit comments

Comments
 (0)