Swap Nodes in Pairs
Problem
val fields is
not allowed.[1,2,3,4]Output[2,1,4,3][1,2,3]Output[2,1,3][]Output[]0 ≤ number of nodes ≤ 100 · 0 ≤ Node.val ≤ 100 · Values must not be modified.
Try it yourself
class Solution {
public ListNode swapPairs(ListNode head) {
}
}
prev → a → b → next is just
three pointer writes: a.next = next, b.next = a,
prev.next = b. A dummy node gives the first pair a prev too.Instinct Nodes joined by next pointers and the task is to reverse, splice, merge, reorder or remove in place - grab a dummy head and rewire pointers carefully.
Memory hack Save next, flip, step - never let go of a rope before you've grabbed the next one.
Open the Linked List Techniques guide →Approaches
Brute ForceArray of Nodes, Swap, Relink
O(n)Space O(n)Copy node references into a list, swap entries i and
i+1 for every even i, then relink the nodes in their new
order and terminate the last one. Easy, since arrays allow random access.
public ListNode swapPairs(ListNode head) { List<ListNode> nodes = new ArrayList<>(); for (ListNode c = head; c != null; c = c.next) nodes.add(c); for (int i = 0; i + 1 < nodes.size(); i += 2) Collections.swap(nodes, i, i + 1); for (int i = 0; i < nodes.size(); i++) { nodes.get(i).next = (i + 1 < nodes.size()) ? nodes.get(i + 1) : null; } return nodes.isEmpty() ? null : nodes.get(0); }
Simple and safe, but O(n) extra memory for something pointers can do in place.
BetterRecursion
O(n)Space O(n)Swap the first two nodes and let recursion solve the rest:
first.next = swapPairs(third), second.next = first, return
second. Base case: fewer than two nodes. Clean, but each pair adds a
stack frame (n/2 frames).
public ListNode swapPairs(ListNode head) { if (head == null || head.next == null) return head; ListNode first = head, second = head.next; first.next = swapPairs(second.next); second.next = first; return second; // new head of this pair }
Elegant and no explicit buffer, yet O(n) call-stack space.
OptimalIterative with Dummy Node
O(n)Space O(1)Keep prev pointing at the node before the current pair (starting at a
dummy). While two nodes remain, rewire the three pointers, then advance
prev to first — which is now the pair's tail.
public ListNode swapPairs(ListNode head) { ListNode dummy = new ListNode(0, head); ListNode prev = dummy; while (prev.next != null && prev.next.next != null) { ListNode first = prev.next, second = first.next; first.next = second.next; second.next = first; prev.next = second; prev = first; // first is now the tail of the pair } return dummy.next; }
Dry run[1,2,3,4]
- initDp1a2b34prev = dummy
- swapD21p34D→2→1, prev=1
- nextD21p3a4bpair (3,4)
- swapD2143p1→4→3, prev=3
- endD2143pprev.next null ✔
Single pass, constant extra space — the expected interview answer.
At a glance
| Level | Approach | Time | Space |
|---|---|---|---|
| Brute Force | Array of Nodes, Swap, Relink | O(n) | O(n) |
| Better | Recursion | O(n) | O(n) |
| Optimal | Iterative with Dummy Node | O(n) | O(1) |
- Swapping
vals instead of nodes — explicitly disallowed. - Writing
prev.next = secondfirst without savingsecond.next— loses the rest of the list. - Advancing
prevtosecond— after the swap the pair's tail isfirst.
- Draw
prev → a → b → nextand list the three writes before coding. - Test empty, single-node and odd-length lists out loud.
- Generalise: this is Reverse Nodes in k-Group with k = 2.