给定一个单链表 L
的头节点 head
,单链表 L
表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4] 输出:[1,4,2,3]
示例 2:
输入:head = [1,2,3,4,5] 输出:[1,5,2,4,3]
代码如下:
class Solution {
public:
void reorderList(ListNode* head) {
if(head==nullptr)
{
return;
}
ListNode* mid=getmid(head);//调用获得中点的函数来定义中点的值
ListNode* l1=head;//在中点处将链表分为两个链表,分别定义两个链表
ListNode* l2=mid->next;
mid->next=nullptr;//在中点的后面断开链表
l2= reverseList(l2);//反转后面的链表
mergeList(l1,l2);//最后合并两个链表
}
//找到链表的中点--快慢指针的方法
ListNode* getmid(ListNode* head)
{
ListNode* slow=head;
ListNode* fast=head;
while(fast->next!=nullptr&&fast->next->next!=nullptr)
{
slow=slow->next;//慢指针每次走一步
fast=fast->next->next;//快指针每次走两步
}
return slow;
}
//反转链表
ListNode* reverseList(ListNode* head)
{
ListNode* prev=nullptr;
ListNode* curr=head;//定义一个指针指向头节点
while(curr!=nullptr)
{
ListNode* nextTemp=curr->next;//先将头节点的下一个保存起来
curr->next=prev;//让头节点的下一个为prev
prev=curr;//让prev指向curr,此时链表已经反转,头节点是prev
curr=nextTemp;//八curr往后移一个,进行下一次循环
}
return prev;
}
//合并两个链表
void mergeList(ListNode* l1,ListNode* l2)
{
ListNode* l1_temp;
ListNode* l2_temp;
while(l1!=nullptr&&l2!=nullptr)
{
l1_temp=l1->next;//将l1->next保存到l1_temp中
l2_temp=l2->next;//将l2->next保存到l2_temp中
//依次连接l1与l2链表中的值
l1->next=l2;//将l1与l2链表连接起来
l1=l1_temp;//l1向后移一个
l2->next=l1;//将l1与l2链表连接起来
l2=l2_temp;//l2向后移一个
}
}
};