451 两两交换链表中的节点
原题网址:https://www.lintcode.com/problem/swap-nodes-in-pairs/description
描述
给一个链表,两两交换其中的节点,然后返回交换后的链表。
您在真实的面试中是否遇到过这个题?
样例
给出 1->2->3->4
, 你应该返回的链表是 2->1->4->3
。
挑战
你的算法只能使用常数的额外空间,并且不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
标签
链表
思路:要形成一个新链表,主要操作就是挂载节点,应该搞清楚在哪个节点上挂载哪个节点。
为操作方便,可以定义一个象征头结点,则当前等待被挂载节点的前驱节点pre的初始值可以设置为象征头结点。
遍历原链表,如果当前节点及当前节点的后继节点都不为NULL时:
1.将当前节点的后继节点的后继节点用一个临时变量保存起来;
2.将当前节点的后继节点挂载到前驱节点pre上;
3.将当前节点的后继节点的next值设置为当前节点,即完成相邻两个节点交换操作;
4.注意!为防止两个节点互相挂载形成闭环,需要将尾部的节点也就是交换后的当前节点next值赋为NULL;
5.更新前驱节点,更新后pre应为位于新链表尾部的当前节点;
6.用临时变量更新当前节点;
注意链表节点数为奇数的情况,即循环结束后,若当前节点不为NULL,说明原链表还剩下一个尾节点需要挂载到新链表上。
AC代码:
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: a ListNode
* @return: a ListNode
*/
ListNode * swapPairs(ListNode * head) {
// write your code here
if (head==NULL)
{
return head;
}
ListNode *tmp=NULL;
ListNode * newhead=new ListNode(0);
ListNode *pre=newhead;//被挂载的前驱节点;
while(head!=NULL&&head->next!=NULL)
{
tmp=head->next->next;//保存后续节点地址;
//交换;
pre->next=head->next;
head->next->next=head;
head->next=NULL; //防止出现闭环;
pre=head;
head=tmp;
}
if (head!=NULL)//若链表节点个数为奇数,将最后一个节点挂载上去;
{
pre->next=head;
}
return newhead->next;
}
};
非挑战版:https://blog.csdn.net/wangyukl/article/details/65936101 这个思路比较直观,就是直接交换两个节点的数据。