Skip to content

Commit c686dd9

Browse files
committed
Add problem 143 - Reorder List
1 parent 46ac44f commit c686dd9

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

problems/linked_list/reorder_list.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from typing import Optional
2+
3+
from problems.util.list_node import ListNode
4+
5+
6+
class ReorderList:
7+
def reorderList(self, head: Optional[ListNode]) -> ListNode | None:
8+
"""
9+
Do not return anything, modify head in-place instead.
10+
"""
11+
# Special case
12+
if head is None or head.next is None:
13+
return head
14+
# Find the middle of the list
15+
middle = self.get_middle(head)
16+
# Divide the list in two halves
17+
head_1, head_2 = head, middle.next
18+
middle.next = None
19+
# Find the reverse of the second half
20+
reverse_head_2 = self.reverse(head_2)
21+
# Merge two lists
22+
while head_1 is not None and reverse_head_2 is not None:
23+
next_1, next_2 = head_1.next, reverse_head_2.next
24+
head_1.next = reverse_head_2
25+
reverse_head_2.next = next_1
26+
head_1 = next_1
27+
reverse_head_2 = next_2
28+
return head
29+
30+
@staticmethod
31+
def get_middle(head: Optional[ListNode]) -> ListNode:
32+
slow, fast = head, head
33+
while fast is not None and fast.next is not None:
34+
slow = slow.next
35+
fast = fast.next.next
36+
return slow
37+
38+
@staticmethod
39+
def reverse(head: Optional[ListNode]) -> ListNode:
40+
previous_node, current_node, next_node = None, head, None
41+
while current_node is not None:
42+
next_node = current_node.next
43+
current_node.next = previous_node
44+
previous_node = current_node
45+
current_node = next_node
46+
return previous_node
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import unittest
2+
3+
from problems.linked_list.reorder_list import ReorderList
4+
from problems.util.list_node import ListNode
5+
6+
7+
def build_list(values):
8+
if not values:
9+
return None
10+
head = ListNode(values[0])
11+
current = head
12+
for value in values[1:]:
13+
current.next = ListNode(value)
14+
current = current.next
15+
return head
16+
17+
18+
def list_to_array(head):
19+
result = []
20+
current = head
21+
while current:
22+
result.append(current.val)
23+
current = current.next
24+
return result
25+
26+
27+
class ReorderListTest(unittest.TestCase):
28+
def setUp(self):
29+
self.reorder_list = ReorderList()
30+
31+
def test_empty_list(self):
32+
head = None
33+
self.reorder_list.reorderList(head)
34+
self.assertIsNone(head)
35+
36+
def test_single_element_list(self):
37+
head = build_list([1])
38+
self.reorder_list.reorderList(head)
39+
self.assertEqual(list_to_array(head), [1])
40+
41+
def test_two_element_list(self):
42+
head = build_list([1, 2])
43+
self.reorder_list.reorderList(head)
44+
self.assertEqual(list_to_array(head), [1, 2])
45+
46+
def test_three_element_list(self):
47+
head = build_list([1, 2, 3])
48+
self.reorder_list.reorderList(head)
49+
self.assertEqual(list_to_array(head), [1, 3, 2])
50+
51+
def test_four_element_list(self):
52+
head = build_list([1, 2, 3, 4])
53+
self.reorder_list.reorderList(head)
54+
self.assertEqual(list_to_array(head), [1, 4, 2, 3])
55+
56+
def test_odd_number_of_elements(self):
57+
head = build_list([1, 2, 3, 4, 5])
58+
self.reorder_list.reorderList(head)
59+
self.assertEqual(list_to_array(head), [1, 5, 2, 4, 3])
60+
61+
def test_even_number_of_elements(self):
62+
head = build_list([1, 2, 3, 4, 5, 6])
63+
self.reorder_list.reorderList(head)
64+
self.assertEqual(list_to_array(head), [1, 6, 2, 5, 3, 4])
65+
66+
def test_get_middle(self):
67+
head = build_list([1, 2, 3, 4, 5])
68+
middle = self.reorder_list.get_middle(head)
69+
self.assertEqual(middle.val, 3)
70+
71+
def test_reverse_list(self):
72+
head = build_list([1, 2, 3, 4, 5])
73+
reversed_head = self.reorder_list.reverse(head)
74+
self.assertEqual(list_to_array(reversed_head), [5, 4, 3, 2, 1])
75+
76+
77+
if __name__ == '__main__':
78+
unittest.main()

0 commit comments

Comments
 (0)