# 24. Swap Nodes in Pairs

LeetCode Problem Link (opens new window)

Given a linked list, swap every two adjacent nodes and return its head. You must use only constant extra space and you may not modify the values in the list's nodes, only nodes themselves may be changed.

24. Swap Nodes in Pairs - Problem Statement

# Approach

This problem can be solved by simple simulation.

It's highly recommended to use a dummy head node. This will simplify the process significantly, otherwise, each operation targeting the head node (which doesn't have a preceding node pointing to it) would need to be handled separately.

If you are not yet familiar with operations involving a dummy head node, consider reviewing the article 0203.Remove Linked List Elements (opens new window).

Next, swap every pair of adjacent elements. It is crucial to draw a diagram here. Without a diagram, handling multiple pointers can easily become confusing, and the order of operations needs to be precise.

Initially, the cur pointer points to the dummy head node, and then proceed with the following three steps:

24. Swap Nodes in Pairs Step 1

After the operations, the linked list looks like this:

24. Swap Nodes in Pairs Step 2

This may provide a clearer visualization:

24. Swap Nodes in Pairs Diagram

Here is the corresponding C++ code implementation: (the comments detail and align with the three steps in the diagram above)

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyHead = new ListNode(0); // Initialize a dummy head node
        dummyHead->next = head; // Connect the dummy head node to the head for easier subsequent node manipulations
        ListNode* cur = dummyHead;
        while(cur->next != nullptr && cur->next->next != nullptr) {
            ListNode* tmp = cur->next; // Save temporary node
            ListNode* tmp1 = cur->next->next->next; // Save another temporary node

            cur->next = cur->next->next;    // Step 1
            cur->next->next = tmp;          // Step 2
            cur->next->next->next = tmp1;   // Step 3

            cur = cur->next->next; // Move cur forward by two nodes for the next swap
        }
        ListNode* result = dummyHead->next;
        delete dummyHead;
        return result;
    }
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  • Time Complexity: O(n)
  • Space Complexity: O(1)

# Further Discussion

Do not place too much emphasis on the runtime statistics represented on LeetCode, such as how many users your submission outperformed. These metrics are not entirely accurate.

As long as you can analyze and determine the time complexity during the coding process, that's sufficient. Regarding LeetCode's runtime metrics, just have a general look.

When I first submitted the above code, it took 8ms, which reportedly outperformed only 6.5% of other submissions, which surprised me because typically there isn’t a better approach than O(n) complexity. Upon resubmitting a few times, the results were reflected as follows:

24. Swap Nodes in Pairs Result

If there are variations in execution times such as 100ms vs. 300ms, they are something to pay attention to. However, if it’s something like 4ms vs. 12ms, where one appears to outperform 80% and the other 20%, there practically isn't any difference—it’s just an estimation error on LeetCode’s part.

# Other Language Versions

# C:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
// Recursive version
struct ListNode* swapPairs(struct ListNode* head){
    // Base cases to terminate recursion: if head does not exist or if there's no next node, just return head
    if(!head || !head->next)
        return head;
    // Create a node pointer type to store the next node of the head
    struct ListNode *newHead = head->next;
    // Update the node two positions ahead and link the head's next pointer to this updated list
    head->next = swapPairs(newHead->next);
    // Set the next node's next pointer to the old head node
    newHead->next = head;
    return newHead;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Iterative version
struct ListNode* swapPairs(struct ListNode* head){
    // Using two pointers to avoid using temporary variables
    typedef struct ListNode ListNode;
    ListNode *fakehead = (ListNode *)malloc(sizeof(ListNode));
    fakehead->next = head;
    ListNode* right = fakehead->next;
    ListNode* left = fakehead;
    while(left && right && right->next ){
        left->next = right->next;
        right->next = left->next->next;
        left->next->next = right;
        left = right;
        right = left->next;
    }
    return fakehead->next;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Java:

// Recursive version
class Solution {
    public ListNode swapPairs(ListNode head) {
        // Base case termination
        if(head == null || head.next == null) return head;
        // Retrieve next node of the current node
        ListNode next = head.next;
        // Perform recursion
        ListNode newNode = swapPairs(next.next);
        // Swap occurs here
        next.next = head;
        head.next = newNode;

        return next;
    }
} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
  public ListNode swapPairs(ListNode head) {
        ListNode dumyhead = new ListNode(-1); // Initialize a dummy head node
        dumyhead.next = head; // Connect the dummy head node to head for easier subsequent node manipulations
        ListNode cur = dumyhead;
        ListNode temp; // Temporary node to save the node following the pair
        ListNode firstnode; // Temporary node to save the first node of the pair
        ListNode secondnode; // Temporary node to save the second node of the pair
        while (cur.next != null && cur.next.next != null) {
            temp = cur.next.next.next;
            firstnode = cur.next;
            secondnode = cur.next.next;
            cur.next = secondnode;       // Step 1
            secondnode.next = firstnode; // Step 2
            firstnode.next = temp;      // Step 3
            cur = firstnode; // Move cur forward, preparing for the next swap
        }
        return dumyhead.next;  
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Swap in a different order for steps 2 and 3, removing the need for the temp node
public ListNode swapPairs(ListNode head) {
    ListNode dummy = new ListNode(0, head);
    ListNode cur = dummy;
    while (cur.next != null && cur.next.next != null) {
        ListNode node1 = cur.next; // First node in the pair
        ListNode node2 = cur.next.next; // Second node in the pair
        cur.next = node2; // Step 1
        node1.next = node2.next; // Step 3
        node2.next = node1; // Step 2
        cur = cur.next.next; // Advance cur
    }
    return dummy.next;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Python:

# Recursive version
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if head is None or head.next is None:
            return head

        # Nodes to be swapped are pre and cur
        pre = head
        cur = head.next
        next = head.next.next
        
        cur.next = pre  # Swap operation
        pre.next = self.swapPairs(next) # Continue swapping the subsequent linked list
        
        return cur
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        dummy_head = ListNode(next=head)
        current = dummy_head
        
        # Both cur's next and next next nodes need to be present for swapping, else swapping complete
        while current.next and current.next.next:
            temp = current.next # Save state before modifying
            temp1 = current.next.next.next
            
            current.next = current.next.next
            current.next.next = temp
            temp.next = temp1
            current = current.next.next
        return dummy_head.next

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# Go:

func swapPairs(head *ListNode) *ListNode {
    dummy := &ListNode{
        Next: head,
    }
    pre := dummy 
    for head != nil && head.Next != nil {
        pre.Next = head.Next
        next := head.Next.Next
        head.Next.Next = head
        head.Next = next
        pre = head 
        head = next
    }
    return dummy.Next
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Recursive version
func swapPairs(head *ListNode) *ListNode {
    if head == nil || head.Next == nil {
        return head
    }
    next := head.Next
    head.Next = swapPairs(next.Next)
    next.Next = head
    return next
}
1
2
3
4
5
6
7
8
9
10

# JavaScript:

var swapPairs = function (head) {
  let ret = new ListNode(0, head), temp = ret;
  while (temp.next && temp.next.next) {
    let cur = temp.next.next, pre = temp.next;
    pre.next = cur.next;
    cur.next = pre;
    temp.next = cur;
    temp = pre;
  }
  return ret.next;
};
1
2
3
4
5
6
7
8
9
10
11
// Recursive version
var swapPairs = function (head) {
  if (head == null || head.next == null) {
    return head;
  }

  let after = head.next;
  head.next = swapPairs(after.next);
  after.next = head;

  return after;
};
1
2
3
4
5
6
7
8
9
10
11
12

# TypeScript:

function swapPairs(head: ListNode | null): ListNode | null {
    const dummyNode: ListNode = new ListNode(0, head);
    let curNode: ListNode | null = dummyNode;
    while (curNode && curNode.next && curNode.next.next) {
        let firstNode: ListNode = curNode.next,
            secNode: ListNode = curNode.next.next,
            thirdNode: ListNode | null = curNode.next.next.next;
        curNode.next = secNode;
        secNode.next = firstNode;
        firstNode.next = thirdNode;
        curNode = firstNode;
    }
    return dummyNode.next;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Kotlin:

fun swapPairs(head: ListNode?): ListNode? {
    val dummyNode = ListNode(0).apply { 
        this.next = head
    }
    var cur: ListNode? = dummyNode
    while (cur?.next != null && cur.next?.next != null) {
        val temp = cur.next
        val temp2 = cur.next?.next?.next
        
        cur?.next = cur.next?.next
        cur?.next?.next = temp
        cur?.next?.next?.next = temp2
        cur = cur?.next?.next
    }
    return dummyNode.next
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Swift:

func swapPairs(_ head: ListNode?) -> ListNode? {
    if head == nil || head?.next == nil {
        return head
    }
    let dummyHead: ListNode = ListNode(-1, head)
    var current: ListNode? = dummyHead
    while current?.next != nil && current?.next?.next != nil {
        let temp1 = current?.next
        let temp2 = current?.next?.next?.next
        
        current?.next = current?.next?.next
        current?.next?.next = temp1
        current?.next?.next?.next = temp2
        
        current = current?.next?.next
    }
    return dummyHead.next
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Scala:

// With dummy head node
object Solution {
  def swapPairs(head: ListNode): ListNode = {
    var dummy = new ListNode(0, head) // Dummy head node
    var pre = dummy
    var cur = head
    // perform swap when the next two nodes are present
    while (pre.next != null && pre.next.next != null) {
      var tmp: ListNode = cur.next.next // save first node of next pair
      pre.next = cur.next // Step 1
      cur.next.next = cur // Step 2
      cur.next = tmp // Step 3
      // setup for the next swap iteration
      pre = cur
      cur = tmp
    }
    // return the node following dummy head
    dummy.next
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# PHP:

// With dummy head node
function swapPairs($head) {
    if ($head == null || $head->next == null) {
        return $head;
    }

    $dummyNode = new ListNode(0, $head);
    $preNode = $dummyNode; // Dummy head node
    $curNode = $head;
    $nextNode = $head->next;
    while($curNode && $nextNode) {
        $nextNextNode = $nextNode->next; // Store subsequent node
        $nextNode->next = $curNode; // swap curNode and nextNode
        $curNode->next = $nextNextNode;
        $preNode->next = $nextNode; // Connect previous node to nextNode

        // Update pointers for next iteration
        $preNode = $preNode->next->next;
        $curNode = $nextNextNode;
        $nextNode = $nextNextNode->next;
    }

    return $dummyNode->next;
}

// Recursive version
function swapPairs($head)
{
    // Base cases for recursion termination
    if ($head === null || $head->next === null) {
        return $head;
    }

    // Determine the new head node of the swapped sequence
    $next = $head->next;
    $head->next = $this->swapPairs($next->next); // Update head node's pointer
    $next->next = $head;  // Update pointer of the new head node
    return $next;  // Return the new head node after swapping
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# Rust:

// With dummy head node
impl Solution {
    pub fn swap_pairs(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        let mut dummy_head = Box::new(ListNode::new(0));
        dummy_head.next = head;
        let mut cur = dummy_head.as_mut();
        while let Some(mut node) = cur.next.take() {
            if let Some(mut next) = node.next.take() {
                node.next = next.next.take();
                next.next = Some(node);
                cur.next = Some(next);
                cur = cur.next.as_mut().unwrap().next.as_mut().unwrap();
            } else {
                cur.next = Some(node);
                cur = cur.next.as_mut().unwrap();
            }
        }
        dummy_head.next
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Recursive
impl Solution {
    pub fn swap_pairs(head: Option<Box<ListNode>>) -> Option<Box<ListNode>> {
        if head.is_none() || head.as_ref().unwrap().next.is_none() {
            return head;
        }

        let mut node = head.unwrap();

        if let Some(mut next) = node.next.take() {
            node.next = Solution::swap_pairs(next.next);
            next.next = Some(node);
            Some(next)
        } else {
            Some(node)
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# C#

// With dummy head node
public ListNode SwapPairs(ListNode head)
{
    var dummyHead = new ListNode();
    dummyHead.next = head;
    ListNode cur = dummyHead;
    while (cur.next != null && cur.next.next != null)
    {
        ListNode tmp1 = cur.next;
        ListNode tmp2 = cur.next.next.next;

        cur.next = cur.next.next;
        cur.next.next = tmp1;
        cur.next.next.next = tmp2;

        cur = cur.next.next;
    }
    return dummyHead.next;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Recursive
public ListNode SwapPairs(ListNode head)
{
    if (head == null || head.next == null) return head;
    var cur = head.next;
    head.next = SwapPairs(head.next.next);
    cur.next = head;
    return cur;
}
1
2
3
4
5
6
7
8
9
Last updated:: 9/4/2025, 3:19:38 PM
Copyright © 2025 keetcoder