Swapping Nodes in a Linked List
Medium · Two Pointers · Explanation and code example
Iteration (One Pass) - II
How it works
This variation uses a slightly different approach: we start right moving only after we have found the k-th node. By decrementing k during traversal, we know exactly when we reach the k-th position. At that moment, we initialize right at the head. From then on, both pointers move together, maintaining their fixed distance until the end.
Steps
- Traverse with
cur, decrementing k each step. - When k equals 1, save
curasleftand setrightto head. - Continue traversing. If
rightexists, advance it along withcur. - When
curreaches the end,rightwill be at the k-th node from the end. - Swap the values of
leftandright. - Return the head.
Complexity
- Time complexity:
O(n) - Space complexity:
O(1)
Things to watch for
Off-By-One Errors in Position Calculation
The k-th node from the beginning is at position k (1-indexed), requiring k-1 advances from the head. The k-th node from the end is at position n-k+1 from the beginning. Confusing 0-indexed and 1-indexed counting or miscalculating the end position leads to swapping the wrong nodes. Carefully trace through a small example to verify your indexing.
Not Starting the Second Pointer at the Right Time
In the one-pass two-pointer approach, the second pointer (right) must start moving from the head exactly when the first pointer reaches the k-th node. Starting too early or too late means right won't land on the k-th node from the end when the first pointer reaches the list's end. The gap between pointers must be exactly k-1 nodes.
Swapping Nodes Instead of Values
The problem asks to swap the values of two nodes, not the nodes themselves. Swapping node pointers requires updating multiple references (including the previous nodes' next pointers), which is more complex and error-prone. Simply swapping left.val and right.val is cleaner and achieves the same result for this problem.
Python code example
from typing import Optional
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapNodes(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
left, right = None, None
cur = head
while cur:
if right:
right = right.next
if k == 1:
left = cur
right = head
k -= 1
cur = cur.next
left.val, right.val = right.val, left.val
return head
C++ code example
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* swapNodes(ListNode* head, int k) {
ListNode* left = nullptr;
ListNode* right = nullptr;
ListNode* cur = head;
while (cur) {
if (right) {
right = right->next;
}
if (k == 1) {
left = cur;
right = head;
}
k--;
cur = cur->next;
}
swap(left->val, right->val);
return head;
}
};
Source and license
Adapted from NeetCode’s source · MIT license. Node types are supplied by LeetCode where needed.