Skip to content

Commit 3437b1f

Browse files
author
Joseph Luce
authored
Update 076_minimum_window_substring.md
1 parent a53d150 commit 3437b1f

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

leetcode/hard/076_minimum_window_substring.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# 76. Minimum Window Substring
22

33
## Two Pointer with Map Solution
4-
- Runtime: O(S * T) but O(S * (S+T)) due to string slicing
4+
- Runtime: O(S * T) + O(T) but O(S * (S+T)) + O(T) due to string slicing
55
- Space: O(S)
66
- S = Number of characters in string S
7-
- T = Number of unique characters in string T
7+
- T = Number of characters in string T
88

99
So the definition of a result requires the substring to contain all characters in T. It then wants the smallest substring.
1010
With that, we have to begin the solution by finding the first instance of that substring.
@@ -65,10 +65,10 @@ def chars_occur_ge(ch_to_n_counts, all_ch_counts):
6565
```
6666

6767
## Two Pointer with Map Solution (Optimized)
68-
- Runtime: O(S)
68+
- Runtime: O(S) + O(T) but O(S * S) + O(T) due to string slicing
6969
- Space: O(S)
7070
- S = Number of characters in string S
71-
- T = Number of unique characters in string T
71+
- T = Number of characters in string T
7272

7373
We can further improve the solution by optimizing the way we check if its a valid substring.
7474
We can still use a dictionary to count the occurances, but we can also keep a separate count for the unique characters in T.
@@ -127,3 +127,52 @@ class CharacterCounter:
127127
def is_valid(self):
128128
return self._n_valid_chars == len(self._source_counts.keys())
129129
```
130+
131+
## Two Pointer with Map Solution (No String slicing)
132+
- Runtime: O(S) + O(T)
133+
- Space: O(S)
134+
- S = Number of characters in string S
135+
- T = Number of characters in string T
136+
137+
```
138+
from collections import defaultdict
139+
from collections import Counter
140+
141+
class Solution:
142+
def minWindow(self, s: str, t: str) -> str:
143+
char_counter = CharacterCounter(t)
144+
left_i, left_i_result, right_i_result = 0, 0, len(s)-1
145+
found = False
146+
for right_i, right_ch in enumerate(s):
147+
char_counter += right_ch
148+
if char_counter.is_valid:
149+
while left_i <= right_i and char_counter.is_valid:
150+
found = True
151+
if right_i-left_i < right_i_result-left_i_result:
152+
right_i_result, left_i_result = right_i, left_i
153+
char_counter -= s[left_i]
154+
left_i += 1
155+
return s[left_i_result:right_i_result+1] if found else ''
156+
157+
class CharacterCounter:
158+
def __init__(self, source_str):
159+
self._ch_to_n_counts = defaultdict(int)
160+
self._source_counts = Counter(source_str)
161+
self._n_valid_chars = 0
162+
163+
def __iadd__(self, char):
164+
self._ch_to_n_counts[char] += 1
165+
if char in self._source_counts and self._ch_to_n_counts[char] == self._source_counts[char]:
166+
self._n_valid_chars += 1
167+
return self
168+
169+
def __isub__(self, char):
170+
self._ch_to_n_counts[char] -= 1
171+
if char in self._source_counts and self._ch_to_n_counts[char] == self._source_counts[char]-1:
172+
self._n_valid_chars -= 1
173+
return self
174+
175+
@property
176+
def is_valid(self):
177+
return self._n_valid_chars == len(self._source_counts.keys())
178+
```

0 commit comments

Comments
 (0)