Skip to content

Commit a35f0ba

Browse files
committed
8/22/23
- nearest_repeated_entries.py - smallest_subarray_covering_set.py
1 parent 4a6ab27 commit a35f0ba

File tree

3 files changed

+102
-6
lines changed

3 files changed

+102
-6
lines changed

elements-of-programming-interviews/problem_mapping.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1520,7 +1520,7 @@ problem_mapping = {
15201520
"total": 505
15211521
},
15221522
"Python: nearest_repeated_entries.py": {
1523-
"passed": 0,
1523+
"passed": 505,
15241524
"total": 505
15251525
}
15261526
},
@@ -1534,7 +1534,7 @@ problem_mapping = {
15341534
"total": 904
15351535
},
15361536
"Python: smallest_subarray_covering_set.py": {
1537-
"passed": 0,
1537+
"passed": 904,
15381538
"total": 904
15391539
}
15401540
},

elements-of-programming-interviews/python/nearest_repeated_entries.py

+39-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,50 @@
22

33
from test_framework import generic_test
44

5+
"""
6+
in: list of strs
7+
out: int, distance between closest two repetitions
8+
9+
edges:
10+
- empty list
11+
- no repetitions (what do we return? -1?)
12+
- all repetitions
13+
- all equal distance
14+
15+
O(n) space, time:
16+
- hash every word to index each time it appears
17+
- hash every word to distance since last occured (inf if first occurence)
18+
- don't need this, just best
19+
- return min distance
20+
21+
Can't do better than O(n) time, need to examine each word
22+
Do better than O(n) space? Need to keep track of each word.
23+
"""
24+
import math
25+
526

627
def find_nearest_repetition(paragraph: List[str]) -> int:
7-
# TODO - you fill in here.
8-
return 0
28+
best = float('inf')
29+
last_idx = {}
30+
for i, word in enumerate(paragraph):
31+
if word in last_idx:
32+
best = min(i-last_idx[word], best)
33+
last_idx[word] = i
34+
return best if not math.isclose(best, float('inf')) else -1
935

1036

1137
if __name__ == '__main__':
38+
"""
39+
cases = [
40+
([], -1),
41+
(["no", "a", "b"], -1),
42+
(["no", "a", "b", "no"], 2),
43+
(["no", "no", "b", "no"], 0)
44+
]
45+
for arg, expected in cases:
46+
actual = find_nearest_repetition(arg)
47+
assert actual == expected, f"{actual} != {expected}"
48+
"""
1249
exit(
1350
generic_test.generic_test_main('nearest_repeated_entries.py',
1451
'nearest_repeated_entries.tsv',

elements-of-programming-interviews/python/smallest_subarray_covering_set.py

+61-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,57 @@
88

99
Subarray = collections.namedtuple('Subarray', ('start', 'end'))
1010

11+
"""
12+
["a", "b", "c", "b", "a", "d", "c", "a", "e", "a", "a", "b", "e"]
13+
| | | | | | |
14+
1 2 1 2 3 1 3
15+
16+
1 ... 2 ...3 ... 1,2,3 ... 3 ... 2 ... 1
17+
18+
"""
19+
20+
# b...... b c e ......... b
21+
# first remove l/r characters that aren't in keywords
22+
23+
# No keywords, no paragraph, no keywords in paragraph?
24+
# assume for now none of these can happen
25+
26+
27+
def find_smallest_subarray_covering_set_attempt_one(paragraph: List[str],
28+
keywords: Set[str]) -> Subarray:
29+
subarr = collections.deque([])
30+
current_kwords = collections.Counter()
31+
left, right = 0, len(paragraph)-1
32+
for i, word in enumerate(paragraph):
33+
if word in keywords:
34+
current_kwords[word] += 1
35+
subarr.append(i)
36+
while subarr and current_kwords[paragraph[subarr[0]]] > 1:
37+
current_kwords[paragraph[subarr[0]]] -= 1
38+
subarr.popleft()
39+
if len(current_kwords) == len(keywords) and ((subarr[-1] - subarr[0]) <= (right-left)):
40+
left, right = subarr[0], subarr[-1]
41+
return Subarray(left, right)
42+
1143

1244
def find_smallest_subarray_covering_set(paragraph: List[str],
1345
keywords: Set[str]) -> Subarray:
14-
# TODO - you fill in here.
15-
return Subarray(0, 0)
46+
counts = collections.Counter()
47+
best = Subarray(0, len(paragraph)-1)
48+
left = 0
49+
for right, word in enumerate(paragraph):
50+
if word not in keywords:
51+
continue
52+
counts[word] += 1
53+
54+
while left < len(paragraph) and not (counts[paragraph[left]] == 1):
55+
if paragraph[left] in counts:
56+
counts[paragraph[left]] -= 1
57+
left += 1
58+
59+
if len(counts) == len(keywords) and ((right - left) <= (best.end - best.start)):
60+
best = Subarray(left, right)
61+
return best
1662

1763

1864
@enable_executor_hook
@@ -37,6 +83,19 @@ def find_smallest_subarray_covering_set_wrapper(executor, paragraph, keywords):
3783

3884

3985
if __name__ == '__main__':
86+
"""
87+
cases = [
88+
(["a", "b", "c", "b", "a", "d", "c", "a", "e", "a", "a", "b", "e"], set(["b", "c", "e"]), Subarray(6, 11)),
89+
(["a", "b", "c", "e", "a"], set(["b", "c", "e"]), Subarray(1, 3)),
90+
(["a", "b", "c", "e", "a", "e"], set(["b", "c", "e"]), Subarray(1, 3)),
91+
(["b", "a", "b", "c", "e", "a", "e"], set(["b", "c", "e"]), Subarray(2, 4)),
92+
(["b", "a", "c", "c", "c", "b", "c", "e", "a", "e"], set(["b", "c", "e"]), Subarray(5, 7))
93+
94+
]
95+
for paragraph, keywords, expected in cases:
96+
actual = find_smallest_subarray_covering_set(paragraph, keywords)
97+
assert expected == actual, f"\nparagraph: {paragraph}\nkeywords: {keywords}\n{expected} != {actual}"
98+
"""
4099
exit(
41100
generic_test.generic_test_main(
42101
'smallest_subarray_covering_set.py',

0 commit comments

Comments
 (0)