Swap nodes in pairs

LeetCode problem 24. Swap Nodes in Pairs.

## Problem description

Given a linked list, swap every two adjacent nodes and return its head.

Example 1
* **Input:** head = [1,2,3,4]
* **Output:** [2,1,4,3]

Example 2
* **Input:** head = []
* **Output:** []

Example 3
* **Input:** head = [1]
* **Output:** [1]

Constraints
* The number of nodes in the list is in the range `[0, 100]`.
* `0 <= Node.val <= 100`

Follow up
Can you solve the problem without modifying the values in the list's nodes? (i.e., Only nodes themselves may be changed.)

## Iterative approach

The **iterative approach** means that we traverse the linked list from left to right, and reverse a pair of nodes during each iteration.

For each iteration, we can use two pointers **`p1`** and **`p2`** to mark the two elements to be swapped, and additional two pointers **`n1`** and **`n2`** to mark the locations of `p1` and `p2` on the next iteration.

The iteration looks like this;

```
p2.next = p1;
p1.next = (n2 == null) ? n1 : n2; // this handles the cases of both odd and even number of nodes
p1 = n1;
p2 = n2;

```

Loop until `p2` reaches null. This happens when either:

* If the total number of nodes is even, both `p1` and `p2` have reached the end (become `null`); or
* If the total number is odd, `p2` has reached the end (becomes null).

### Complexity analysis

#### Time complexity

* For *n* total nodes there are (*n*/2) iterations.
* Each iteration performs the job in O(1) time.

So the total time complexity is **O(n)**.

#### Space complexity

* On the stack we only store four pointers: `p1`, `p2`, `n1`, `n2`.
* We do not need to allocate additional objects on heap.

So the space complexity is **O(1)**.

### Solutions

#### C++

```
/\*\*
 \* 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\* swapPairs(ListNode\* head) {
 // iterative approach

 // if we have 0 or 1 node, then no reverse
 if ((head == nullptr) || (head->next == nullptr)) {
 return head;
 }

 ListNode \*p1 = head, \*p2 = head->next;
 ListNode \*const newHead = p2;
 while (p2 != nullptr) {
 // locate next two elements
 ListNode \*next1 = p2->next;
 ListNode \*next2 = (next1 == nullptr) ? nullptr : next1->next;

 // relocate pointers
 p2->next = p1;
 p1->next = (next2 == nullptr) ? next1 : next2;

 // advance p1 and p2
 p1 = next1;
 p2 = next2;
 }

 return newHead;
 }
};

```

#### Java

```
/\*\*
 \* Definition for singly-linked list.
 \* public class ListNode {
 \* int val;
 \* ListNode next;
 \* ListNode() {}
 \* ListNode(int val) { this.val = val; }
 \* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 \* }
 \*/
class Solution {
 public ListNode swapPairs(ListNode head) {
 // iterative approach

 // if we have 0 or 1 node, then no reverse
 if ((head == null) || (head.next == null)) {
 return head;
 }

 ListNode p1 = head, p2 = head.next;
 final ListNode newHead = p2;
 while (p2 != null) {
 // locate next two elements
 ListNode next1 = p2.next;
 ListNode next2 = (next1 == null) ? null : next1.next;

 // relocate pointers
 p2.next = p1;
 p1.next = (next2 == null) ? next1 : next2;

 // advance p1 and p2
 p1 = next1;
 p2 = next2;
 }

 return newHead;
 }
}

```

## Recursive approach

The **recursive approach** means that we reverse the first two nodes of the entire list, and then the first two nodes of the sublist starting at the 3rd element, and then first two nodes of the sublist starting at the 5th element… and so on.

The recursion is as follows:

* **Base case**: A sublist with zero (null) or one node is not reversed. Return the head of the sublist directly.
* **Recursive case**: Reverse the first two nodes. Then recursively apply the procedure to the sublist starting from the third node.

### Complexity analysis

#### Time complexity

* For *n* total nodes we have *n*/2 levels of recursions.
* Each level of recursion swaps the first two nodes of the sublist.

So the total time complexity must be **O(n)**.

#### Space complexity

Stack
Each time we allocate pointers `p1` and `p2` to swap the first two elements. In each recursion two such pointers are used.
So the space complexity on stack is **O(n)**.
Heap
We did not allocate additional memory on heap. So the space complexity on heap is **O(1).**
The total space complexity is **O(n)**.

### Solutions

#### C++

```
/\*\*
 \* 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\* swapPairs(ListNode\* head) {
 // recursive approach

 // base case
 if ((head == nullptr) || (head->next == nullptr)) {
 return head;
 }

 // recursion
 ListNode \*p1 = head, \*p2 = head->next;
 ListNode \*newHead = p2;
 ListNode \*subHead = p2->next;
 p2->next = p1;
 p1->next = swapPairs(subHead);

 return newHead;
 }
};

```

#### Java

```
/\*\*
 \* Definition for singly-linked list.
 \* public class ListNode {
 \* int val;
 \* ListNode next;
 \* ListNode() {}
 \* ListNode(int val) { this.val = val; }
 \* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 \* }
 \*/
class Solution {
 public ListNode swapPairs(ListNode head) {
 // recursive approach

 // base case
 if ((head == null) || (head.next == null)) {
 return head;
 }

 // recursion
 ListNode p1 = head, p2 = head.next;
 ListNode newHead = p2;
 ListNode subHead = p2.next;
 p2.next = p1;
 p1.next = swapPairs(subHead);

 return newHead;
 }
}

```

## See also

* Reverse a linked list
* Reverse a linked list II