Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head)
{
if(NULL == head)
return NULL;
/*tmp:exchange the value*/
int tmp = 0;
struct ListNode *p = head;
struct ListNode *pnext = p->next;
while(p&&pnext)
{
/*exchange p and pnext*/
tmp = p->val;
p->val = pnext->val;
pnext->val = tmp;
/*prepare for next loop*/
p = pnext->next;
/*p not null,then use p->next*/
if(p)
pnext = p->next;
}
return head;
}
上面解法实际上和下面的解法一样,下面这个解法更加精炼:
/**
* 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) {
ListNode * p = head;
while(p && p->next)
{
swap(p->val,p->next->val);
p = p->next->next;
}
return head;
}
};
但是题目中明确有要求:Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.不能更改结点中的值,我们上面这两种解法都修改了结点的值。
一种比较巧妙的解法是:
/**
* 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)
{
ListNode **pp = &head,*p,*pnext;
while((p =*pp) && (pnext = p->next))
{
p->next = pnext->next;
pnext->next = p;
*pp = pnext;
pp = &(p->next);
}
return head;
}
};
一个可以调试运行的完整程序如下,方便理解上面的代码:
#include <iostream>
using namespace std;
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) {}
};
ListNode* swapPairs(ListNode* head) {
//p point to current node,pnext point the next node of p
//pp point to the current start node,including deal with the actual head after swap(first loop)
ListNode **pp = &head,*p,*pnext;
while((p=*pp) && (pnext=p->next))
{
//swap the node p & pnext
p->next = pnext->next;
pnext->next = p;
//modify the start node,pointer to pointer ,so we can change pointer itelf
//if we remove line *pp = pnext,we will lost 2 4 in {1,2,3,4}
*pp = pnext;
pp=&(p->next);
}
for(ListNode *it = head;it != NULL;it=it->next)
{
cout<<it->val<<endl;
}
return head;
}
int main()
{
ListNode last(4);
ListNode third(3,&last);
ListNode second(2,&third);
ListNode first(1,&second);
swapPairs(&first);
return 0;
}
2021.07.07更新:
一种比较好理解的写法:
/**
* 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) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* node = dummy;
int i = 0;
while(head && head->next)
{
ListNode* first = head;
ListNode* second = head->next;
//第一个结点指向第二节点下一个元素
first->next = second->next;
//第二个结点指向下一个结点
second->next = first;
//串联链表
node->next = second;
node = first;
//交换之后head每次只需更新为head->next
head = head->next;
}
return dummy->next;
}
};