Reorder List

Problem

https://leetcode.com/problems/reorder-list/

You are given the head of a singly linked-list. The list can be represented as:

L0 → L1 → … → Ln - 1 → Ln

Reorder the list to be on the following form:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …

You may not modify the values in the list’s nodes. Only nodes themselves may be changed.

Example 1:

image1

Input: head = [1,2,3,4]
Output: [1,4,2,3]

Example 2:

image2

Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]

Constraints:

  • The number of nodes in the list is in the range [1, 5 * 10:sup:`4`].

  • 1 <= Node.val <= 1000

Pattern

Linked List, Two Pointers, Stack, Recursion

Approaches

Code

from __future__ import annotations


class ListNode:
    """Node in a linked list."""

    def __init__(self, val: int = 0, next: ListNode | None = None):
        self.val = val
        self.next = next

    @classmethod
    def from_list(cls, vals: list[int]) -> ListNode | None:
        head: ListNode | None = None
        for v in vals:
            if head is None:
                head = ListNode(v)
                node = head
            else:
                node.next = ListNode(v)
                node = node.next
        return head

    def to_list(self) -> list:
        result = []
        node = self
        while node:
            result.append(node.val)
            node = node.next
        return result


def reorderList(head: ListNode | None) -> None:
    """
    Do not return anything, modify head in-place instead.
    """
    slow = head
    fast = head.next
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

    prev = None
    while slow:
        original_next = slow.next
        slow.next = prev
        prev = slow
        slow = original_next

    while head and prev:
        original_head_next = head.next
        original_prev_next = prev.next

        head.next = prev
        prev.next = original_head_next

        head = original_head_next
        prev = original_prev_next

Test

>>> from reorder_list__split_and_merge import reorderList, ListNode
>>> head = ListNode.from_list([1, 2, 3, 4])
>>> reorderList(head)
>>> head.to_list()
[1, 4, 2, 3]
>>> head = ListNode.from_list([1, 2, 3, 4, 5])
>>> reorderList(head)
>>> head.to_list()
[1, 5, 2, 4, 3]
class reorder_list__split_and_merge.ListNode(val: int = 0, next: ListNode | None = None)

Bases: object

Node in a linked list.

classmethod from_list(vals: list[int]) ListNode | None
to_list() list
reorder_list__split_and_merge.reorderList(head: ListNode | None) None

Do not return anything, modify head in-place instead.