The question is to swap each pair in the linked list. And the requirement is to use constant space.
Solution 1: use recurrence. Each recurrence could be views as swapping current head and head->next. Then head->next->next = swapPairs(head->next->next);
Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(!head) return NULL;
if(!head->next) return head;
ListNode *prev = head;
ListNode *next = head->next;
prev->next = next->next;
next->next = prev;
head = next;
head->next->next = swapPairs(head->next->next);
return head;
}
};
Solution 2: Directly swap pairs in the linked list.
Code:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(!head) return NULL;
if(!head->next) return head;
//swap head and head->next
ListNode *prev = head;
ListNode *next = head->next;
prev->next = next->next;
next->next = prev;
head = next;
<span style="white-space:pre"> </span>//go to next pair and retain the link between current pair and next pair(prev_prev->prev->next
<span style="white-space:pre"> </span>//where prev->next is the next pair and prev_prev->prev is the link between current pair and the next pair)
ListNode *prev_prev = head->next;
prev = prev_prev->next;
if(!prev) return head;//if new prev is null, then we have no next pair, just return
next = prev->next;
if(!next) return head;//if new prev is not null but new next is null, then we do not need to
<span style="white-space:pre"> </span> //swap, just return
while(true){
prev->next = next->next;//swap
next->next = prev; //swap
prev_prev->next = next;//update the link between the pair we are swapping and the previous pair,
<span style="white-space:pre"> </span> //say 1,2,3,4,5,6. After we swap 3,4, we have 2->1 ....4->3.
<span style="white-space:pre"> </span> //we have to update the link from 1 to 4. Otherwise 1 would be
<span style="white-space:pre"> </span> //still linked to 3.
//move to next pair
prev_prev = prev;//now 2,1,4,3,5,6. we move prev_prev from 1 to 3, (5,6) is next pair so
<span style="white-space:pre"> </span> //we move prev to 5, and next to 6.
prev = prev->next;
if(!prev) break;
next = prev->next;
if(!next) break;
}
return head;
}
};