Skip to content

Commit 00b17c4

Browse files
committed
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.
1 parent 03a4251 commit 00b17c4

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

strings/min_window_substring.py

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

0 commit comments

Comments
 (0)