思路
先找出链表的中间节点,再把中间节点之后的链表反转,最后再把两个链表合并。总体的思路不难,但我在合并两个链表这一步卡了很久。
代码
/**
* 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:
void reorderList(ListNode* head) {
ListNode* mid=get_mid_node(head);
ListNode* head2=reverse_node(mid);
//由于反转链表之后,head最后一个元素会和head2最后一个元素相同
//如果是while(head2),偶数时会出现问题,所以就干脆舍弃head2最后一个节点,反正这节点在head中有
while(head2->next){
//head:1->2->3
//head2:5->4->3
//先把各自的下一位保存起来
ListNode* nxt=head->next,*nxt2=head2->next;
//再把next指针分别指向对方
head->next=head2;
head2->next=nxt;
//各自往后推
head=nxt;
head2=nxt2;
}
}
//获取中间节点
ListNode* get_mid_node(ListNode* node){
ListNode* l1=node,*l2=node;
while(l2&&l2->next){
l2=l2->next->next;
l1=l1->next;
}
return l1;
}
//反转链表
ListNode* reverse_node(ListNode* node){
ListNode* cur=node,*pre=nullptr;
while(cur){
ListNode* tem=cur->next;
cur->next=pre;
pre=cur;
cur=tem;
}
return pre;
}
};