题目:给定一个链表,交换两个相邻的节点,并返回头节点。
例子:给定 1->2->3->4,返回 2->1->4->3;
这道题看上去很简单,其实也很简单,交换两个节点并不难,难在如何让前面已经交换过的一对节点能正确地和后面那对交换过的节点链接起来!
思路:我们可以创建一个新的头节点phead,phead.next = head,然后我们每次交换之后更新这个phead的next指针,并且更新指向phead的指针,就可以啦!
举个例子:
最开始时,我们的链表是这样:
现在我们交换1和2(让2指向1,1指向3):
然后更新phead.next和ph以及a和b:
这样1和2就正确的完成了交换,并且ph.next将在下一步更新时指向交换后的3和4中的4!
我们来看一下代码:
别忘了注意代码的鲁棒性!当head为nullptr时程序不能崩溃!
/**
* 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)
{
//这个指针ph->next指向每一个交换对的第一个节点
//我们会在每次交换完成后将其赋值以使得每对节点可以正确链接
ListNode phead = ListNode(0);
phead.next = head;
ListNode *ph = &phead;
ListNode *a = nullptr, *b = nullptr;
//当a或者b为nullptr的时候就可以结束了
//如果链表有偶数个节点,则最后一步时a为nullptr,退出循环
//如果链表有奇数个节点,则最后一步使b为nullptr,退出循环
//一旦a为nullptr就不用再检验第二个条件了,所以这里不会造成程序崩溃
while((a = ph->next) && (b = a->next))
{
//交换
a->next = b->next;
b->next = a;
//更新起始节点
ph->next = b;
//开始下一对的交换
ph = a;
}
return phead.next;
}
};
下面是运行结果: