Skip to content

Commit 4dc37cb

Browse files
committed
Add partition_linked_list algorithm with comprehensive doctests
1 parent a71618f commit 4dc37cb

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""
2+
Partitions a linked list around a value x such that all nodes less than x come before
3+
nodes greater than or equal to x. The original relative order of the nodes in each
4+
partition should be preserved. The partition value x can appear anywhere in the "right
5+
partition" and it does not need to appear between the left and right partitions.
6+
"""
7+
8+
from __future__ import annotations
9+
10+
from dataclasses import dataclass
11+
12+
13+
@dataclass
14+
class ListNode:
15+
value: int = 0
16+
next_node: ListNode | None = None
17+
18+
19+
def create_linked_list(values: list[int]) -> ListNode | None:
20+
"""Helper function to create a linked list from a list of values."""
21+
if not values:
22+
return None
23+
head = ListNode(values[0])
24+
current = head
25+
for value in values[1:]:
26+
current.next_node = ListNode(value)
27+
current = current.next_node
28+
return head
29+
30+
31+
def linked_list_to_list(head: ListNode | None) -> list[int]:
32+
"""Helper function to convert a linked list to a list of values."""
33+
values = []
34+
current = head
35+
while current:
36+
values.append(current.value)
37+
current = current.next_node
38+
return values
39+
40+
41+
def partition_linked_list(head: ListNode | None, x: int) -> ListNode | None:
42+
"""
43+
Args:
44+
head: The head of the linked list.
45+
x: The partition value.
46+
47+
Returns:
48+
The head of the partitioned linked list.
49+
50+
Examples:
51+
>>> linked_list_to_list(
52+
... partition_linked_list(create_linked_list([1, 4, 3, 2, 5, 2]), 3)
53+
... )
54+
[1, 2, 2, 4, 3, 5]
55+
>>> linked_list_to_list(
56+
... partition_linked_list(create_linked_list([1, 2, 3]), 10)
57+
... )
58+
[1, 2, 3]
59+
>>> linked_list_to_list(
60+
... partition_linked_list(create_linked_list([5, 6, 7]), 3)
61+
... )
62+
[5, 6, 7]
63+
>>> linked_list_to_list(
64+
... partition_linked_list(create_linked_list([3, 5, 8, 5, 10, 2, 1]), 5)
65+
... )
66+
[3, 2, 1, 5, 8, 5, 10]
67+
>>> linked_list_to_list(
68+
... partition_linked_list(create_linked_list([1]), 5)
69+
... )
70+
[1]
71+
>>> linked_list_to_list(partition_linked_list(None, 5))
72+
[]
73+
"""
74+
if head is None:
75+
return None
76+
77+
if head.next_node is None:
78+
return head
79+
80+
left_head = ListNode(0) # Dummy head for the left partition
81+
right_head = ListNode(0) # Dummy head for the right partition
82+
left = left_head
83+
right = right_head
84+
85+
current: ListNode | None = head
86+
while current:
87+
if current.value < x:
88+
left.next_node = current
89+
left = current
90+
else:
91+
right.next_node = current
92+
right = current
93+
current = current.next_node
94+
95+
right.next_node = None # Terminate the right partition
96+
left.next_node = right_head.next_node # Connect the two partitions
97+
98+
return left_head.next_node # Return the head of the new partitioned list
99+
100+
101+
if __name__ == "__main__":
102+
import doctest
103+
104+
doctest.testmod()

0 commit comments

Comments
 (0)