Skip to content

Commit 29c894d

Browse files
committed
8/24/23
- stack_with_max.py - delete_node_from_list.py - do_lists_overlap.py - do_terminated_lists_overlap.py - int_as_list_add.py
1 parent 38e3085 commit 29c894d

File tree

6 files changed

+186
-21
lines changed

6 files changed

+186
-21
lines changed

elements-of-programming-interviews/problem_mapping.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ problem_mapping = {
740740
"total": 106
741741
},
742742
"Python: do_terminated_lists_overlap.py": {
743-
"passed": 0,
743+
"passed": 106,
744744
"total": 106
745745
}
746746
},
@@ -754,7 +754,7 @@ problem_mapping = {
754754
"total": 120
755755
},
756756
"Python: do_lists_overlap.py": {
757-
"passed": 0,
757+
"passed": 120,
758758
"total": 120
759759
}
760760
},
@@ -768,7 +768,7 @@ problem_mapping = {
768768
"total": 512
769769
},
770770
"Python: delete_node_from_list.py": {
771-
"passed": 0,
771+
"passed": 512,
772772
"total": 512
773773
}
774774
},
@@ -866,7 +866,7 @@ problem_mapping = {
866866
"total": 2002
867867
},
868868
"Python: int_as_list_add.py": {
869-
"passed": 0,
869+
"passed": 2002,
870870
"total": 2002
871871
}
872872
}
@@ -882,7 +882,7 @@ problem_mapping = {
882882
"total": 101
883883
},
884884
"Python: stack_with_max.py": {
885-
"passed": 0,
885+
"passed": 101,
886886
"total": 101
887887
}
888888
},

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

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

88
# Assumes node_to_delete is not tail.
99
def deletion_from_list(node_to_delete: ListNode) -> None:
10-
# TODO - you fill in here.
11-
return
10+
if node_to_delete:
11+
node_to_delete.data = node_to_delete.next.data
12+
node_to_delete.next = node_to_delete.next.next
1213

1314

1415
@enable_executor_hook

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

+112-2
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,103 @@
66
from test_framework.test_failure import TestFailure
77
from test_framework.test_utils import enable_executor_hook
88

9+
"""
10+
Cases:
11+
- No cycle, no overlap
12+
- Cycle, no overlap
13+
- No cycle, overlap
14+
- Cycle, overlap
915
10-
def overlapping_lists(l0: ListNode, l1: ListNode) -> Optional[ListNode]:
11-
# TODO - you fill in here.
16+
if only one is cyclic:
17+
return no overlap
18+
if both are cyclic:
19+
get beginning of cycle for both. Starting at one,
20+
if it wraps all the way around without reaching the other's beginning
21+
of cycle, no overlap
22+
else:
23+
shorten to equal length, use
24+
previous method
25+
"""
26+
27+
28+
def get_list_len(head: ListNode):
29+
fast = slow = head
30+
i = 0
31+
while slow:
32+
slow = slow.next
33+
i += 1
34+
if fast:
35+
fast = fast.next
36+
if fast:
37+
fast = fast.next
38+
if fast and fast is slow:
39+
return -1
40+
return i
41+
42+
43+
def check_noncyclic_overlap(l0, l0_len, l1, l1_len):
44+
while l0_len > l1_len:
45+
l0 = l0.next
46+
l0_len -= 1
47+
48+
while l1_len > l0_len:
49+
l1 = l1.next
50+
l1_len -= 1
51+
52+
while l0 is not l1:
53+
l0 = l0.next
54+
l1 = l1.next
55+
56+
return l0
57+
58+
59+
def get_cycle_head(head: ListNode):
60+
slow = fast = head
61+
while True:
62+
slow = slow.next
63+
fast = fast.next.next
64+
if slow is fast:
65+
break
66+
67+
slow = head
68+
while slow is not fast:
69+
slow = slow.next
70+
fast = fast.next
71+
72+
return fast
73+
74+
75+
def check_cyclic_overlap(l0, l1):
76+
l0_cycle_head = get_cycle_head(l0)
77+
l1_cycle_head = get_cycle_head(l1)
78+
if l0_cycle_head is l1_cycle_head:
79+
return l0_cycle_head
80+
81+
curr = l0_cycle_head.next
82+
while curr is not l0_cycle_head:
83+
if curr is l1_cycle_head:
84+
return curr
85+
curr = curr.next
1286
return None
1387

1488

89+
def overlapping_lists(l0: ListNode, l1: ListNode) -> Optional[ListNode]:
90+
if not l0 or not l1:
91+
return None
92+
l0_len = get_list_len(l0)
93+
l1_len = get_list_len(l1)
94+
95+
# One's a cycle, the other is not
96+
if -1 in [l0_len, l1_len] and l0_len != l1_len:
97+
return None
98+
99+
# Neither is cyclic
100+
if l0_len != -1:
101+
return check_noncyclic_overlap(l0, l0_len, l1, l1_len)
102+
else:
103+
return check_cyclic_overlap(l0, l1)
104+
105+
15106
@enable_executor_hook
16107
def overlapping_lists_wrapper(executor, l0, l1, common, cycle0, cycle1):
17108
if common:
@@ -65,7 +156,26 @@ def overlapping_lists_wrapper(executor, l0, l1, common, cycle0, cycle1):
65156
raise TestFailure('Invalid result')
66157

67158

159+
def print_list(head):
160+
seen = set()
161+
while head:
162+
if id(head) in seen:
163+
print("cycle detected; quitting.")
164+
return
165+
seen.add(id(head))
166+
print(f"node: {head.data}")
167+
head = head.next
168+
169+
68170
if __name__ == '__main__':
171+
"""
172+
head = curr = ListNode(0, None)
173+
for i in range(1, 10):
174+
curr.next = ListNode(i, None)
175+
curr = curr.next
176+
# curr.next = head.next.next.next
177+
print(overlapping_lists(head, head.next.next.next.next).data)
178+
"""
69179
exit(
70180
generic_test.generic_test_main('do_lists_overlap.py',
71181
'do_lists_overlap.tsv',

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

+25-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,33 @@
55
from test_framework.test_failure import TestFailure
66
from test_framework.test_utils import enable_executor_hook
77

8+
# if lists are same length and overlap, they overlap at the same place
9+
# so shorten one if necessary, then compare node-by-node.
10+
11+
12+
def get_list_len(head: ListNode):
13+
size = 0
14+
while head:
15+
size += 1
16+
head = head.next
17+
return size
18+
819

920
def overlapping_no_cycle_lists(l0: ListNode, l1: ListNode) -> ListNode:
10-
# TODO - you fill in here.
11-
return ListNode()
21+
l0_len = get_list_len(l0)
22+
l1_len = get_list_len(l1)
23+
while l0_len > l1_len:
24+
l0 = l0.next
25+
l0_len -= 1
26+
while l0_len < l1_len:
27+
l1 = l1.next
28+
l1_len -= 1
29+
30+
while l0 is not l1:
31+
l0 = l0.next
32+
l1 = l1.next
33+
34+
return l0 if l0 is l1 and l0 is not None else None
1235

1336

1437
@enable_executor_hook

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

+19-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,27 @@
33
from list_node import ListNode
44
from test_framework import generic_test
55

6+
# TODO: Negatives
7+
68

79
def add_two_numbers(L1: ListNode, L2: ListNode) -> Optional[ListNode]:
8-
# TODO - you fill in here.
9-
return None
10+
# NOTE: Only works for nonnegatives
11+
if not L2 or not L1:
12+
return L1 if L1 else L2
13+
14+
head = curr = ListNode(-1, None)
15+
carry = 0
16+
while L1 or L2 or carry:
17+
op1 = L1.data if L1 else 0
18+
op2 = L2.data if L2 else 0
19+
digit = (op1 + op2 + carry) % 10
20+
carry = (op1 + op2 + carry) // 10
21+
curr.next = ListNode(digit, None)
22+
curr = curr.next
23+
L1 = L1.next if L1 else L1
24+
L2 = L2.next if L2 else L2
25+
26+
return head.next
1027

1128

1229
if __name__ == '__main__':

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

+22-8
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,25 @@
33

44

55
class Stack:
6+
def __init__(self):
7+
self.data = []
8+
self._maxes = []
9+
610
def empty(self) -> bool:
7-
# TODO - you fill in here.
8-
return True
11+
return len(self.data) == 0
912

1013
def max(self) -> int:
11-
# TODO - you fill in here.
12-
return 0
14+
return self._maxes[-1]
1315

1416
def pop(self) -> int:
15-
# TODO - you fill in here.
16-
return 0
17+
if self.data[-1] == self._maxes[-1]:
18+
self._maxes.pop()
19+
return self.data.pop()
1720

1821
def push(self, x: int) -> None:
19-
# TODO - you fill in here.
20-
return
22+
self.data.append(x)
23+
if len(self._maxes) == 0 or self.data[-1] >= self._maxes[-1]:
24+
self._maxes.append(x)
2125

2226

2327
def stack_tester(ops):
@@ -51,6 +55,16 @@ def stack_tester(ops):
5155

5256

5357
if __name__ == '__main__':
58+
"""
59+
s = Stack()
60+
s.push(10)
61+
print(s.max())
62+
s.push(12)
63+
print(s.max())
64+
s.pop()
65+
print(s.max())
66+
67+
"""
5468
exit(
5569
generic_test.generic_test_main('stack_with_max.py',
5670
'stack_with_max.tsv', stack_tester))

0 commit comments

Comments
 (0)