Skip to content

Commit 38e3085

Browse files
committed
8/23/23
- delete_from_list.py - is_string_palindromic_punctuation.py - phone_number_mnemonic.py - reverse_sublist.py - reverse_words.py - sorted_lists_merge.py - is_list_cyclic.py
1 parent a35f0ba commit 38e3085

8 files changed

+168
-20
lines changed

elements-of-programming-interviews/problem_mapping.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ problem_mapping = {
546546
"total": 305
547547
},
548548
"Python: is_string_palindromic_punctuation.py": {
549-
"passed": 0,
549+
"passed": 305,
550550
"total": 305
551551
}
552552
},
@@ -560,7 +560,7 @@ problem_mapping = {
560560
"total": 103
561561
},
562562
"Python: reverse_words.py": {
563-
"passed": 0,
563+
"passed": 103,
564564
"total": 103
565565
}
566566
},
@@ -676,7 +676,7 @@ problem_mapping = {
676676
"total": 505
677677
},
678678
"Python: delete_from_list.py": {
679-
"passed": 0,
679+
"passed": 457,
680680
"total": 457
681681
},
682682
"Python: insert_in_list.py": {
@@ -698,7 +698,7 @@ problem_mapping = {
698698
"total": 501
699699
},
700700
"Python: sorted_lists_merge.py": {
701-
"passed": 0,
701+
"passed": 501,
702702
"total": 501
703703
}
704704
},
@@ -712,7 +712,7 @@ problem_mapping = {
712712
"total": 210
713713
},
714714
"Python: reverse_sublist.py": {
715-
"passed": 0,
715+
"passed": 210,
716716
"total": 210
717717
}
718718
},
@@ -726,7 +726,7 @@ problem_mapping = {
726726
"total": 102
727727
},
728728
"Python: is_list_cyclic.py": {
729-
"passed": 0,
729+
"passed": 102,
730730
"total": 102
731731
}
732732
},
@@ -1548,7 +1548,7 @@ problem_mapping = {
15481548
"total": 629
15491549
},
15501550
"Python: smallest_subarray_covering_all_values.py": {
1551-
"passed": 0,
1551+
"passed": 13,
15521552
"total": 629
15531553
}
15541554
},
@@ -1988,7 +1988,7 @@ problem_mapping = {
19881988
"total": 102
19891989
},
19901990
"Python: phone_number_mnemonic.py": {
1991-
"passed": 0,
1991+
"passed": 102,
19921992
"total": 102
19931993
}
19941994
},

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
# Delete the node past this one. Assume node is not a tail.
99
def delete_after(node: ListNode) -> None:
10-
# TODO - you fill in here.
11-
return
10+
if node and node.next:
11+
node.next = node.next.next
1212

1313

1414
@enable_executor_hook

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

+17-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,23 @@
88

99

1010
def has_cycle(head: ListNode) -> Optional[ListNode]:
11-
# TODO - you fill in here.
12-
return None
11+
if not head:
12+
return head
13+
slow = fast = head
14+
while fast and fast.next:
15+
fast = fast.next.next
16+
slow = slow.next
17+
if fast is slow:
18+
break
19+
20+
if not fast or not fast.next:
21+
return None
22+
23+
slow = head
24+
while fast is not slow:
25+
fast = fast.next
26+
slow = slow.next
27+
return fast
1328

1429

1530
@enable_executor_hook

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

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
from test_framework import generic_test
22

3+
# empty is palindrome
4+
# " " is palindrome (it's also empty)
5+
36

47
def is_palindrome(s: str) -> bool:
5-
# TODO - you fill in here.
8+
l, r = 0, len(s)-1
9+
while l <= r:
10+
while l < len(s) and not s[l].isalnum():
11+
l += 1
12+
while r >= 0 and not s[r].isalnum():
13+
r -= 1
14+
if (0 <= l <= r < len(s)) and not s[l].lower() == s[r].lower():
15+
return False
16+
r -= 1
17+
l += 1
618
return True
719

820

921
if __name__ == '__main__':
22+
assert is_palindrome("")
23+
assert is_palindrome(" ")
24+
assert is_palindrome("a")
25+
assert is_palindrome("aa")
26+
assert is_palindrome(" a a ")
27+
assert is_palindrome(" a a ")
28+
assert not is_palindrome("ab")
29+
assert not is_palindrome("ab ")
30+
assert not is_palindrome(" ab ")
1031
exit(
1132
generic_test.generic_test_main(
1233
'is_string_palindromic_punctuation.py',

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

+27-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,34 @@
33
from test_framework import generic_test, test_utils
44

55

6+
KEYPAD = {
7+
"2": "ABC",
8+
"3": "DEF",
9+
"4": "GHI",
10+
"5": "JKL",
11+
"6": "MNO",
12+
"7": "PQRS",
13+
"8": "TUV",
14+
"9": "WXYZ",
15+
}
16+
17+
618
def phone_mnemonic(phone_number: str) -> List[str]:
7-
# TODO - you fill in here.
8-
return []
19+
solutions = []
20+
21+
def process_digit(phone_number, i, base):
22+
if i == len(phone_number):
23+
solutions.append("".join(base))
24+
return
25+
if phone_number[i] in ["0", "1"]:
26+
process_digit(phone_number, i+1, base + [phone_number[i]])
27+
else:
28+
new_chars = KEYPAD[phone_number[i]]
29+
for char in new_chars:
30+
process_digit(phone_number, i+1, base + [char])
31+
32+
process_digit(phone_number, 0, [])
33+
return solutions
934

1035

1136
if __name__ == '__main__':

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

+56-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,67 @@
44
from test_framework import generic_test
55

66

7+
def reverse_list(start: ListNode, end: ListNode) -> None:
8+
if start == end:
9+
return
10+
prev = None
11+
curr = start
12+
while prev != end:
13+
nextNext = curr.next
14+
curr.next = prev
15+
prev = curr
16+
curr = nextNext
17+
18+
719
def reverse_sublist(L: ListNode, start: int,
820
finish: int) -> Optional[ListNode]:
9-
# TODO - you fill in here.
10-
return None
21+
if not start or start == finish:
22+
return L
23+
pre_start_node = start_node = end_node = post_end_node = None
24+
curr = L
25+
i = 1
26+
while curr:
27+
if i == start-1:
28+
pre_start_node = curr
29+
elif i == start:
30+
start_node = curr
31+
elif i == finish:
32+
end_node = curr
33+
elif i == finish+1:
34+
post_end_node = curr
35+
i += 1
36+
curr = curr.next
37+
38+
reverse_list(start_node, end_node)
39+
# if there was a pre-start node, it points now to end node
40+
if pre_start_node:
41+
pre_start_node.next = end_node
42+
# if there was a post-end node, the old start node now points to it.
43+
if post_end_node:
44+
start_node.next = post_end_node
45+
return L if pre_start_node else end_node
1146

1247

1348
if __name__ == '__main__':
49+
"""
50+
start_i = 1
51+
finish_i = 9
52+
head = start = finish = end = ListNode(0, None)
53+
54+
for i in range(1, 10):
55+
end.next = ListNode(i, None)
56+
end = end.next
57+
if i == start_i:
58+
start = end
59+
if i == finish_i:
60+
finish = end
61+
reverse_sublist(head, start_i, finish_i)
62+
63+
while (head):
64+
print(f"Node: {head.data}")
65+
head = head.next
66+
67+
"""
1468
exit(
1569
generic_test.generic_test_main('reverse_sublist.py',
1670
'reverse_sublist.tsv', reverse_sublist))

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

+20-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,26 @@
66

77
# Assume s is a list of strings, each of which is of length 1, e.g.,
88
# ['r', 'a', 'm', ' ', 'i', 's', ' ', 'c', 'o', 's', 't', 'l', 'y'].
9+
10+
def reverse_arr(arr, l, r):
11+
while l <= r:
12+
tmp = arr[l]
13+
arr[l] = arr[r]
14+
arr[r] = tmp
15+
l += 1
16+
r -= 1
17+
18+
919
def reverse_words(s):
10-
# TODO - you fill in here.
20+
if not s:
21+
return s
22+
reverse_arr(s, 0, len(s)-1)
23+
l = 0
24+
for r, c in enumerate(s):
25+
if c == " ":
26+
reverse_arr(s, l, r-1)
27+
l = r+1
28+
reverse_arr(s, l, r)
1129
return
1230

1331

@@ -21,6 +39,7 @@ def reverse_words_wrapper(executor, s):
2139

2240

2341
if __name__ == '__main__':
42+
# print(reverse_words("Alice likes Bob"))
2443
exit(
2544
generic_test.generic_test_main('reverse_words.py', 'reverse_words.tsv',
2645
reverse_words_wrapper))

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

+16-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,22 @@
66

77
def merge_two_sorted_lists(L1: Optional[ListNode],
88
L2: Optional[ListNode]) -> Optional[ListNode]:
9-
# TODO - you fill in here.
10-
return None
9+
head = ListNode(-1, None)
10+
curr = head
11+
while L1 and L2:
12+
if L1.data <= L2.data:
13+
curr.next = L1
14+
L1 = L1.next
15+
else:
16+
curr.next = L2
17+
L2 = L2.next
18+
curr = curr.next
19+
20+
if L1:
21+
curr.next = L1
22+
if L2:
23+
curr.next = L2
24+
return head.next
1125

1226

1327
if __name__ == '__main__':

0 commit comments

Comments
 (0)