-
Notifications
You must be signed in to change notification settings - Fork 0
/
shortest_string.py
89 lines (69 loc) · 2.24 KB
/
shortest_string.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#
# Copyright (c) 2019 David Davis. All rights reserved.
#
# python 3.7 compatible
#
from collections import Counter
from collections import defaultdict
"""
Input: string = “this is a test string”, pattern = “tist”
Output: Minimum window is “t stri”
Input: string = “geeksforgeeks”, pattern = “ork”
Output: Minimum window is “ksfor”
"""
def main():
while True:
input_string = input("string: ")
if not input_string:
break
alphabet = input("alphabet: ")
if not alphabet:
break
result = getMinSubstr(input_string, alphabet)
print("result: {}\n".format(result))
def makeCountDict(string):
return Counter(string)
def makeIndexDict(string, alphabet):
result = defaultdict(list)
for i in range(0, len(string)):
if string[i] in alphabet:
result[string[i]].append(i)
else:
return result
def getSubstringIndexes(indexDict, countDict, begin, end):
indexes = []
for k, v in countDict.items():
arr = indexDict.get(k, [])
arr = list(filter(lambda index: index >= begin and index <= end, arr))
if len(arr) < v:
#print("getSubstringIndexes: {} begin {} end {} k {} v {}".format(arr, begin, end, k, v))
return False, None, None
else:
indexes.extend(arr[0:v])
else:
#print("getSubstringIndexes: {} begin {} end {}".format(indexes, begin, end))
return True, min(indexes), max(indexes)
def getMinSubstr(string, alphabet):
indexes = []
indexDict = makeIndexDict(string, alphabet)
countDict = makeCountDict(alphabet)
begin = 0
end = len(string) - 1
endIndex = end
hasAll, begin, end = getSubstringIndexes(indexDict, countDict, begin, end)
if not hasAll:
return ""
else:
indexes.append((begin, end))
while True:
hasAll, begin, end = getSubstringIndexes(indexDict, countDict, begin + 1, endIndex)
if not hasAll:
break
else:
indexes.append((begin, end))
#print(indexes)
lengths = list(map(lambda x: x[1] - x[0], indexes))
shortest = lengths.index(min(lengths))
begin, end = indexes[shortest]
return string[begin : end + 1]
main()