Reorder List - JS Solution

JS
Editorial

Solution explanation

Solution explanation

Approach

  • Step 0: Understand the intuition behind the approach.
    The target pattern is L0 β†’ Ln β†’ L1 β†’ Ln-1 β†’ L2 β†’ Ln-2 β†’ .... Recognize that this is a reordering where we alternately take one node from the beginning and one from the end of the list, gradually moving inward from both sides.

    For lists with an odd number of nodes, the single middle node naturally becomes the last node in the reordered sequence after all end-pairs are consumed. We ensure this by keeping the middle node in the first half.

    To access β€œend” nodes in forward order, we reverse the second half so it can be traversed from what was the tail toward the middle. Once reversed, the second half provides nodes in exactly the order needed to alternate with the first half, all done in-place.
  • Step 1: Define the two halves.
    We conceptually split the list into:
    • Even length: halves of equal size.
    • Odd length: the first half has one extra node (the middle), which will be the final node after reordering.
  • Step 2: Find the tail of the first half (split point).
    Use two pointers, but initialize them with a deliberate offset to control where the split lands: the fast pointer starts at head.next and moves two steps at a time, while the slow pointer starts at head and moves one step at a time.

    Continue while fast and fast.next both exist β€” meaning the fast pointer has not yet reached or exceeded the end. When this condition fails, the slow pointer will be positioned exactly at the tail of the first half, which serves as the perfect split point for reversing and merging later:
    • Even length: slow stops at the end of the left half.
    • Odd length: slow stops on the middle node (kept in the first half), which guarantees it becomes the last node after merging.
  • Step 3: Reverse the second half.
    Sever the list after the first-half tail (slow.next = null) and reverse the remaining nodes. This makes the original tail the head of the reversed second half so we can traverse those β€œend” elements forward during merge.
  • Step 4: Merge the halves by alternating nodes.
    Interleave nodes from both halves while second !== null: take one from the first half, then one from the reversed second half, and repeat. Before each relink, temporarily store each pointer’s next so you don’t lose access to the remainder of either list.
    • Even length: both halves exhaust at the same time β€” they become null together, yielding a perfect alternation.
    • Odd length: second becomes null first; the extra node in the first half (the middle) is already in place and naturally remains as the final node.
    After linking first.next to the current second and second.next to the previously stored first.next, advance both pointers by assigning the stored next references.
  • Step 5: Why this works.
    Reversing the second half converts β€œtake from the end” into a simple forward traversal. Alternating links between the unchanged first half and the reversed second half weaves the list from the outside in, achieving the target pattern with only pointer updates and no extra storage.
  • Step 6: Result.
    The head now points to the reordered sequence L0 β†’ Ln β†’ L1 β†’ Ln-1 β†’ L2 β†’ Ln-2 β†’ …, built entirely in-place.

Time Complexity

O(n) β€” a linear scan to find the split, a linear scan over the second half to reverse it, and a linear scan to merge.

Space Complexity

O(1) β€” the algorithm reuses the same nodes and simply rewires their next pointers in place, without allocating any additional list structures.

Visucodize editorial solution titled JS Solution for LeetCode's Reorder List coding problem. Includes code and may include explanation. You can animate the code step by step using the provided input by clicking the run button, or fork it locally to update the code and input for custom visualization. View the original problem at https://leetcode.com/problems/reorder-list.