Skip to content

Commit 7cf493e

Browse files
wistrasypre-commit-ci[bot]cclauss
authored
Min Window Substring (#12133)
* Added an algorithm to the strings sub folder which finds the smallest substring of a given string which contains all of the characters in another given string. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Formatting Fixes * Fixed a spelling issue * Fixed incorrect function name in test cases * Fixed incorrect function name in test cases * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added link to leetcode. * updating DIRECTORY.md --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: cclauss <cclauss@users.noreply.github.com>
1 parent 692d38f commit 7cf493e

2 files changed

Lines changed: 90 additions & 0 deletions

File tree

‎DIRECTORY.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,7 @@
16041604
* [Lower](strings/lower.py)
16051605
* [Manacher](strings/manacher.py)
16061606
* [Min Cost String Conversion](strings/min_cost_string_conversion.py)
1607+
* [Min Window Substring](strings/min_window_substring.py)
16071608
* [Naive String Search](strings/naive_string_search.py)
16081609
* [Ngram](strings/ngram.py)
16091610
* [Palindrome](strings/palindrome.py)

‎strings/min_window_substring.py‎

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
def min_window(search_str: str, target_letters: str) -> str:
2+
"""
3+
Given a string to search, and another string of target char_dict,
4+
return the smallest substring of the search string that contains
5+
all target char_dict.
6+
7+
This is somewhat modified from my solution to the problem
8+
"Minimum Window Substring" on leetcode.
9+
https://leetcode.com/problems/minimum-window-substring/description/
10+
11+
>>> min_window("Hello World", "lWl")
12+
'llo W'
13+
>>> min_window("Hello World", "f")
14+
''
15+
16+
This solution uses a sliding window, alternating between shifting
17+
the end of the window right until all target char_dict are contained
18+
in the window, and shifting the start of the window right until the
19+
window no longer contains every target character.
20+
21+
Time complexity: O(target_count + search_len) ->
22+
The algorithm checks a dictionary at most twice for each character
23+
in search_str.
24+
25+
Space complexity: O(search_len) ->
26+
The primary contributor to additional space is the building of a
27+
dictionary using the search string.
28+
"""
29+
30+
target_count = len(target_letters)
31+
search_len = len(search_str)
32+
33+
# Return if not possible due to string lengths.
34+
if search_len < target_count:
35+
return ""
36+
37+
# Build dictionary with counts for each letter in target_letters
38+
char_dict = {}
39+
for ch in target_letters:
40+
if ch not in char_dict:
41+
char_dict[ch] = 1
42+
else:
43+
char_dict[ch] += 1
44+
45+
# Initialize window
46+
window_start = 0
47+
window_end = 0
48+
49+
exists = False
50+
min_window_len = search_len + 1
51+
52+
# Start sliding window algorithm
53+
while window_end < search_len:
54+
# Slide window end right until all search characters are contained
55+
while target_count > 0 and window_end < search_len:
56+
cur = search_str[window_end]
57+
if cur in char_dict:
58+
char_dict[cur] -= 1
59+
if char_dict[cur] >= 0:
60+
target_count -= 1
61+
window_end += 1
62+
temp = window_end - window_start
63+
64+
# Check if window is the smallest found so far
65+
if target_count == 0 and temp < min_window_len:
66+
min_window = [window_start, window_end]
67+
exists = True
68+
min_window_len = temp
69+
70+
# Slide window start right until a search character exits the window
71+
while target_count == 0 and window_start < window_end:
72+
cur = search_str[window_start]
73+
window_start += 1
74+
if cur in char_dict:
75+
char_dict[cur] += 1
76+
if char_dict[cur] > 0:
77+
break
78+
temp = window_end - window_start + 1
79+
80+
# Check if window is the smallest found so far
81+
if temp < min_window_len and target_count == 0:
82+
min_window = [window_start - 1, window_end]
83+
min_window_len = temp
84+
target_count = 1
85+
86+
if exists:
87+
return search_str[min_window[0] : min_window[1]]
88+
else:
89+
return ""

0 commit comments

Comments
 (0)