Using a Stack
Intuition
We can use a stack to access nodes from the end of the list easily. First, push all nodes onto a stack. Then, starting from the head, alternately take nodes from the front (via traversal) and from the back (via the stack). We process half the list this way, then terminate the list with a null pointer. The stack gives us O(1) access to the last unprocessed node without needing to reverse anything.
Algorithm
- Push all nodes onto a stack.
- Calculate the total number of nodes. We need to interleave `(count + 1) / 2` nodes from the front with the rest from the stack.
- Starting at `head`, for each of the first half of nodes, pop a node from the stack and insert it after the current node.
- Advance the current pointer past the inserted node.
- After processing, set the last node's `next` to null to terminate the list.
O(n)SpaceO(n)Code (C++ · Java · Python · Go)
class Solution {
public:
void reorderList(ListNode* head) {
if (!head || !head->next) return;
stack<ListNode*> stk;
ListNode* curr = head;
while (curr) {
stk.push(curr);
curr = curr->next;
}
int count = stk.size();
curr = head;
for (int i = 0; i < count / 2; i++) {
ListNode* back = stk.top();
stk.pop();
back->next = curr->next;
curr->next = back;
curr = back->next;
}
curr->next = nullptr;
}
};class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null) return;
Deque<ListNode> stack = new ArrayDeque<>();
ListNode curr = head;
while (curr != null) {
stack.push(curr);
curr = curr.next;
}
int count = stack.size();
curr = head;
for (int i = 0; i < count / 2; i++) {
ListNode back = stack.pop();
back.next = curr.next;
curr.next = back;
curr = back.next;
}
curr.next = null;
}
}def reorderList(head: Optional[ListNode]) -> None:
if not head or not head.next:
return
stack = []
curr = head
while curr:
stack.append(curr)
curr = curr.next
count = len(stack)
curr = head
for _ in range(count // 2):
back = stack.pop()
back.next = curr.next
curr.next = back
curr = back.next
curr.next = Nonefunc reorderList(head *ListNode) {
if head == nil || head.Next == nil {
return
}
var stack []*ListNode
curr := head
for curr != nil {
stack = append(stack, curr)
curr = curr.Next
}
count := len(stack)
curr = head
for i := 0; i < count/2; i++ {
back := stack[len(stack)-1]
stack = stack[:len(stack)-1]
back.Next = curr.Next
curr.Next = back
curr = back.Next
}
curr.Next = nil
}