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