题目
链表:两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100
代码
/**
* 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(0,head);//创建一个节点,数值为0,指向的下一个节点为头结点,相当于在原链表的头部插入一个新节点
ListNode* pre=dummy;
ListNode* first=head;
ListNode* second=NULL;//因为不知道刚开始头结点后是否有数据
while(first&&first->next)
{
second=first->next;
ListNode* nxt=second->next;//因为nxt在随时变化
pre->next=second;//因为从这一步开始到倒数第三步是断链重连
second->next=first;
first->next=nxt;
pre=first;//后两步是在断链重连后,更新指针指向为下一轮交换做准备
first=nxt;
}
return dummy->next;//dummy指向并没有改变,直接返回dummy的下一个节点即链表头结点
}
};
原理图
原理解释
提示:算法流程及解释在代码中已标注
增加一个虚拟节点为了避免掉很多边界条件的处理
需要定义四个指针:
pre指针:指向需要交换节点的前一个节点
first指针:指向第一个需要交换的节点
second指针:指向要交换的第二个节点
nxt指针:指向下一组要交换节点的第一个节点
流程:
①second的下一个节点指向first
②first指针的下一个节点指向nxt
③pre指针的下一个节点指向second
④pre后移一个节点指向first
⑤first指向的节点更改为下一轮需要交换节点的第一个节点nxt
小结
这个算法可以应用在各种需要交换节点的场景,如反转链表、两两交换节点等操作。在实际的面试或工程中,对链表操作的熟练掌握能够帮助我们更好地解决问题。
原理图借鉴哔站华南溜达虎,如有侵权联系删除。