Skip to content
DSAPrep

    ↑↓ to move · Enter to open · Esc to close

    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

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

    Output: [1,4,2,3]

    Example 2

    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^4].
    • 1 <= Node.val <= 1000
    View original on LeetCode ↗

    The target order interleaves the list with itself reversed: first-from-front, first-from-back, second-from-front, second-from-back, and so on. That “zip from both ends” shape is easy to produce with an array, but the optimal approach gets there using only pointer rewrites: split the list in half, reverse the second half, then merge the two halves alternately.

    Copy Into an Array

    Time O(n)Space O(n)

    Dump every node into a list, then use two indices — one starting at the front, one at the back — to rewire next pointers in the zigzag order directly from the array. This is easy to get right, but it needs O(n) extra space to hold the array of node references.

    class ListNode:
    def __init__(self, val=0, next=None):
    self.val = val
    self.next = next
    class Solution:
    def reorderList(self, head: ListNode | None) -> None:
    nodes = []
    node = head
    while node:
    nodes.append(node)
    node = node.next
    lo, hi = 0, len(nodes) - 1
    while lo < hi:
    nodes[lo].next = nodes[hi]
    lo += 1
    if lo == hi:
    break
    nodes[hi].next = nodes[lo]
    hi -= 1
    nodes[lo].next = None

    Correct and straightforward, but every node reference is duplicated into the array — unnecessary, since the nodes and their relative order already exist in the list itself.

    Split, Reverse, Merge In-Place

    OptimalTime O(n)Space O(1)

    Three pointer-only steps, no extra storage:

    1. Find the middle of the list with the slow/fast pointer trick, and split it into a front half and a back half.
    2. Reverse the back half in place (same technique as reversing a whole list).
    3. Merge the two halves by alternating nodes: one from the front half, one from the reversed back half, repeat.
    class Solution:
    def reorderList(self, head: ListNode | None) -> None:
    if not head or not head.next:
    return
    # 1. Find the middle (slow ends on the last node of the front half)
    slow, fast = head, head
    while fast.next and fast.next.next:
    slow = slow.next
    fast = fast.next.next
    # 2. Reverse the second half
    second = slow.next
    slow.next = None # cut the list into two halves
    prev = None
    while second:
    next_node = second.next
    second.next = prev
    prev = second
    second = next_node
    # 3. Merge the two halves alternately
    first, second = head, prev
    while second:
    first_next, second_next = first.next, second.next
    first.next = second
    second.next = first_next
    first, second = first_next, second_next

    Watch the three phases (split, reverse, merge): nodes never move in the picture and only next arrows change, which is exactly what keeps the extra space at O(1).

    1 Split2 Reverse3 Merge
    slow1fast1prev—first—second—
    1
    2
    3
    4
    ▲ slow▲ fast
    1 / 10
    currentresult

    slow and fast both start at the head. Each pass moves fast two nodes and slow one, so slow lands on the last node of the front half.

    Why it’s correct: after the split, the front half holds L0..Lk in order and the reversed back half holds Ln..Lk+1 in order — interleaving them one at a time produces exactly L0, Ln, L1, Ln-1, ..., matching the required pattern. Complexity: finding the middle, reversing, and merging are each a single O(n) pass over the list, with only a constant number of pointer variables → O(n) time, O(1) space — this is optimal, since every node’s next pointer must be touched at least once to reorder the list.

    More Linked List practice