Skip to content

Commit ecdffc0

Browse files
committed
Add sum_linked_lists with doctests
1 parent a71618f commit ecdffc0

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
Given two numbers represented by linked lists, where each node
3+
contains a single digit, write a function that adds the two
4+
numbers and returns the sum as a linked list. The digits are
5+
stored in reverse order, meaning the 1's digit is at the
6+
head of the list.
7+
"""
8+
9+
from __future__ import annotations
10+
11+
from dataclasses import dataclass
12+
13+
14+
@dataclass
15+
class ListNode:
16+
value: int = 0
17+
next_node: ListNode | None = None
18+
19+
20+
def create_linked_list(values: list[int]) -> ListNode | None:
21+
"""
22+
Helper function to create a linked list from a list of values.
23+
24+
>>> head = create_linked_list([2, 4, 3])
25+
>>> (head.value, head.next_node.value, head.next_node.next_node.value)
26+
(2, 4, 3)
27+
>>> create_linked_list([]) is None
28+
True
29+
"""
30+
if not values:
31+
return None
32+
head = ListNode(values[0])
33+
current = head
34+
for value in values[1:]:
35+
current.next_node = ListNode(value)
36+
current = current.next_node
37+
return head
38+
39+
40+
def linked_list_to_list(head: ListNode | None) -> list[int]:
41+
"""
42+
Helper function to convert a linked list to a list of values.
43+
44+
>>> head = ListNode(2)
45+
>>> head.next_node = ListNode(4)
46+
>>> head.next_node.next_node = ListNode(3)
47+
>>> linked_list_to_list(head)
48+
[2, 4, 3]
49+
>>> linked_list_to_list(None)
50+
[]
51+
"""
52+
values = []
53+
current = head
54+
while current:
55+
values.append(current.value)
56+
current = current.next_node
57+
return values
58+
59+
60+
def sum_linked_lists(l1: ListNode | None, l2: ListNode | None) -> ListNode | None:
61+
"""
62+
Adds two numbers represented by linked lists and returns the sum as a linked list.
63+
64+
Args:
65+
l1: The head of the first linked list.
66+
l2: The head of the second linked list.
67+
Returns:
68+
The head of the linked list representing the sum of the two numbers.
69+
>>> l1 = create_linked_list([2, 4, 3]) # Represents the number 342
70+
>>> l2 = create_linked_list([5, 6, 4]) # Represents the number 465
71+
>>> linked_list_to_list(sum_linked_lists(l1, l2)) # Represents the number 807
72+
[7, 0, 8]
73+
>>> l1 = create_linked_list([0]) # Represents the number 0
74+
>>> l2 = create_linked_list([0]) # Represents the number 0
75+
>>> linked_list_to_list(sum_linked_lists(l1, l2)) # Represents the number 0
76+
[0]
77+
>>> l1 = create_linked_list([9, 9, 9, 9, 9, 9, 9]) # Represents the number 9999999
78+
>>> l2 = create_linked_list([9, 9, 9, 9]) # Represents the number 9999
79+
>>> linked_list_to_list(sum_linked_lists(l1, l2)) # Represents the number 10009998
80+
[8, 9, 9, 9, 0, 0, 0, 1]
81+
"""
82+
dummy_head = ListNode(0)
83+
current = dummy_head
84+
carry = 0
85+
86+
while l1 or l2 or carry:
87+
val1 = l1.value if l1 else 0
88+
val2 = l2.value if l2 else 0
89+
90+
total = val1 + val2 + carry
91+
carry = total // 10
92+
current.next_node = ListNode(total % 10)
93+
current = current.next_node
94+
95+
if l1:
96+
l1 = l1.next_node
97+
if l2:
98+
l2 = l2.next_node
99+
100+
return dummy_head.next_node

0 commit comments

Comments
 (0)