Linked List
Swap Nodes in Pairs
DESCRIPTION (inspired by Leetcode.com)
Given a reference head of type ListNode that is the head of a singly linked list, write a function to swap every two adjacent nodes and return its head.
You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)
Example 1: input:
output:
Explanation: 5 and 4 are swapped, 3 and 2 are swapped, and 1 is left alone.
Example 2: input:
output:
Explanation: 1 and 2 are swapped, 3 and 4 are swapped.
// class ListNode {
// int val;
// ListNode next;
// }
public class Solution {
public ListNode swapPairs(ListNode head) {
// Your code goes here
}
}Run your code to see results here
Have suggestions or found something wrong?
Solution
Since we can't modify the values in the nodes, our function needs to swap the nodes by traversing the list and updating the next pointers of the nodes.
This question is an example of how using a dummy node simplifies a solution by removing the need for special logic for swapping the first two nodes in the list. To understand why, let's first look at how to swap a pair of nodes in a linked list.
Let's say we want to swap the pair of nodes first and second in the linked list below:
We need to perform 3 operations:
1). Since we need the node before first to point to second instead of first, we need a pointer prev which references the node before first. Then, we can update prev.next to point to second.
2). We need to update first.next to point to second.next.
3). Finally, we need to update second.next to point to first.
Once that is complete, we can move to the next pair of nodes to swap.
Need for a Dummy Node
As we just saw, swapping a pair of nodes requires a pointer to node before the first node in the pair we want to swap. This is not a problem when we are swapping nodes in the middle of the list, but it is when we are swapping the first pair of nodes in the list because there is no node before head!
We fix this by introducing a dummy node that points to the head of the list. This guarantees that each node in the original list has a node before it, meaning we can swap all nodes in the list using the same logic.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
swap nodes in pairs
0 / 1
From there, we can initialize two pointers, prev and first. first will point to the first node in the pair we want to swap, and prev points to the node before first, which is the dummy node to start. We also initialize the pointer second to point to the node after first.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
create dummy node
0 / 2
We then perform the same 3 operations we discussed earlier to swap the pair of nodes:
1). Update prev.next to point to second. 2). Update first.next to point to second.next. 3). Update second.next to point to first.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
identify pair: 5 and 4
0 / 3
Now, with first and second swapped, we move prev and first to prepare for the next iteration. first now points to the node right before the next pair of nodes, so we update prev to point to first and first to point to first.next. After that, we update second to point to first.next, and our pointers are in the same state to perform the same 3 operations to swap the next pair of nodes.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
second.next → 5
0 / 2
Termination
We can stop the loop when first is None, or when first.next is None. When there an even number of nodes in the list, first will be None when all pairs of nodes have been swapped. When there is an odd number of nodes, first.next will be None when first is at the last node in the list, which we can't swap.
After the loop terminates, we return dummy.next, which is the head of the list with all pairs of nodes swapped.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
no more pairs to swap
0 / 1
Implementation
Here's the complete dummy node approach that elegantly handles all edge cases:
public ListNode swapPairs(ListNode head) {// Create dummy node to simplify edge casesListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy;// Process pairs while both nodes existwhile (prev.next != null && prev.next.next != null) {// Identify the two nodes to swapListNode first = prev.next;ListNode second = prev.next.next;// Perform the swap by adjusting pointersprev.next = second; // Link previous to second nodefirst.next = second.next; // Link first to node after secondsecond.next = first; // Link second to first (completing swap)// Move prev to the end of swapped pair for next iterationprev = first;}return dummy.next; // Return new head}
Code
To construct the linked list that is used in the animation below, provide a list of integers nodes. Each integer in nodes is used as the value of a node in the linked list, and the order of the integers in nodes will be the order of the nodes in the linked list.
For example, if nodes = [1, 2, 3], the linked list will be 1 -> 2 -> 3.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
swap nodes in pairs
0 / 16
Edge Cases
Empty List
When the list is empty, head is None. The while loop never runs, and we return dummy.next, which is equal to None.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
swap nodes in pairs
0 / 3
One Node
When there is only one node in the list, first is the only node in the list, and first.next is None. The while loop never runs, and we return dummy.next, which is head with the single node.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
swap nodes in pairs
0 / 4
Two Nodes
When there are two nodes in the list, first is the first node, and second is the second node. The while loop runs once to swap the two nodes, after which fast is None so the loop terminates. We return dummy.next, which is the head of the list with the two nodes swapped.
class ListNode {int val;ListNode next;ListNode() {}ListNode(int val) { this.val = val; }ListNode(int val, ListNode next) { this.val = val; this.next = next; }}public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy, first = head;while (first != null && first.next != null) {ListNode second = first.next;// swap nodesprev.next = second;first.next = second.next;second.next = first;prev = first;first = first.next;}return dummy.next;}
swap nodes in pairs
0 / 10
What is the time complexity of this solution?
O(n!)
O(m * n)
O(n)
O(4ⁿ)