🧠
Brute Force (Recursive Swapping)
💡 Starting with recursion helps understand the problem by breaking it down into smaller subproblems. It’s intuitive but can lead to stack overflow for very large lists.
Intuition
Swap the first two nodes, then recursively swap the rest of the list. The base case is when there are fewer than two nodes left.
Algorithm
- If the list is empty or has only one node, return it as is.
- Swap the first two nodes by adjusting their next pointers.
- Recursively call the function on the rest of the list starting from the third node.
- Connect the swapped first pair to the result of the recursive call and return the new head.
💡 The recursion makes the problem easier to understand by focusing on just two nodes at a time, but keeping track of pointers is tricky.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def swapPairs(head: ListNode) -> ListNode:
if not head or not head.next:
return head
first_node = head
second_node = head.next
first_node.next = swapPairs(second_node.next)
second_node.next = first_node
return second_node
# Driver code to test
if __name__ == '__main__':
# Create linked list 1->2->3->4
n4 = ListNode(4)
n3 = ListNode(3, n4)
n2 = ListNode(2, n3)
n1 = ListNode(1, n2)
new_head = swapPairs(n1)
# Print swapped list
curr = new_head
while curr:
print(curr.val, end=' ')
curr = curr.next
print()
Line Notes
if not head or not head.next:Base case: if fewer than two nodes, no swap needed
first_node = headIdentify the first node of the current pair
second_node = head.nextIdentify the second node of the current pair
first_node.next = swapPairs(second_node.next)Recursively swap the rest of the list and link to first node
second_node.next = first_nodeComplete the swap by pointing second node to first node
return second_nodeReturn new head of the swapped pair
class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
}
public class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) return head;
ListNode firstNode = head;
ListNode secondNode = head.next;
firstNode.next = swapPairs(secondNode.next);
secondNode.next = firstNode;
return secondNode;
}
public static void main(String[] args) {
ListNode n4 = new ListNode(4);
ListNode n3 = new ListNode(3); n3.next = n4;
ListNode n2 = new ListNode(2); n2.next = n3;
ListNode n1 = new ListNode(1); n1.next = n2;
Solution sol = new Solution();
ListNode newHead = sol.swapPairs(n1);
ListNode curr = newHead;
while (curr != null) {
System.out.print(curr.val + " ");
curr = curr.next;
}
System.out.println();
}
}
Line Notes
if (head == null || head.next == null) return head;Base case: no swap if less than two nodes
ListNode firstNode = head;Mark first node of pair
ListNode secondNode = head.next;Mark second node of pair
firstNode.next = swapPairs(secondNode.next);Recursively swap remaining list and link
secondNode.next = firstNode;Swap current pair by reversing pointers
return secondNode;Return new head after swap
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if (!head || !head->next) return head;
ListNode* firstNode = head;
ListNode* secondNode = head->next;
firstNode->next = swapPairs(secondNode->next);
secondNode->next = firstNode;
return secondNode;
}
};
int main() {
ListNode* n4 = new ListNode(4);
ListNode* n3 = new ListNode(3); n3->next = n4;
ListNode* n2 = new ListNode(2); n2->next = n3;
ListNode* n1 = new ListNode(1); n1->next = n2;
Solution sol;
ListNode* newHead = sol.swapPairs(n1);
ListNode* curr = newHead;
while (curr) {
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
return 0;
}
Line Notes
if (!head || !head->next) return head;Base case: stop recursion if less than two nodes
ListNode* firstNode = head;First node in current pair
ListNode* secondNode = head->next;Second node in current pair
firstNode->next = swapPairs(secondNode->next);Recursively swap rest and link to first node
secondNode->next = firstNode;Swap pointers to reverse current pair
return secondNode;Return new head of swapped pair
function ListNode(val, next = null) {
this.val = val;
this.next = next;
}
function swapPairs(head) {
if (!head || !head.next) return head;
let firstNode = head;
let secondNode = head.next;
firstNode.next = swapPairs(secondNode.next);
secondNode.next = firstNode;
return secondNode;
}
// Driver code
const n4 = new ListNode(4);
const n3 = new ListNode(3, n4);
const n2 = new ListNode(2, n3);
const n1 = new ListNode(1, n2);
const newHead = swapPairs(n1);
let curr = newHead;
while (curr) {
console.log(curr.val);
curr = curr.next;
}
Line Notes
if (!head || !head.next) return head;Base case: no swap if fewer than two nodes
let firstNode = head;Identify first node of pair
let secondNode = head.next;Identify second node of pair
firstNode.next = swapPairs(secondNode.next);Recursively swap rest and link to first node
secondNode.next = firstNode;Swap pointers to reverse current pair
return secondNode;Return new head after swap
Each node is visited once, but recursion adds call stack overhead proportional to n/2 pairs.
💡 For n=20, about 20 operations plus 10 recursive calls on the stack.
Interview Verdict: Accepted but not optimal for very large lists due to recursion depth
Recursion is elegant but risks stack overflow; good for understanding but not always practical.