思路:
题目要求从链表尾部开始,逐个插入头部结点之中(每隔一个) ,相当于三个小题的拼接:找到链表中间结点,反转链表,插入结点。
前两个小题在之前的做题过程中已经解决,直接把这两题的代码拿来用就可以。只需解决第三个问题,设置两个指针分别遍历两个链表,循环条件为p2不空,因为我们是要把后半部分逐个插入前半部分,所以只判断p2即可,p2不空前半部分必不空。设置r指针记录p2后继,循环插入。插入一个结点后,p1指针后移,注意此时不是p1=p1->next而是p1=p2->next,因为此时p1后继为p2,需要再往后走一步才是下一个要插入位置的前驱。
tips:注意前半部分链表要断开,不然报错。
/**
* 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* reverseList(ListNode* head){//反转链表
if(!head) return NULL;
ListNode*cur=head,*pre=NULL;
while(cur){
ListNode*temp=cur->next;
cur->next=pre;pre=cur;cur=temp;
}
return pre;
}
ListNode* endFirstHalf(ListNode* head){//找到中间结点
ListNode*fast=head,*slow=head;
while(fast->next!=NULL && fast->next->next!=NULL){
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
void reorderList(ListNode* head) {
ListNode*firsthalf=endFirstHalf(head);//找链表中间结点或前半部分最后一个结点
ListNode*secondstart=reverseList(firsthalf->next);//反转后半部分
firsthalf->next=nullptr;//前后断开
ListNode*p1=head,*p2=secondstart;
while(p2){//拼接
ListNode*r=p2->next;//r指针记录p2后继
p2->next=p1->next;p1->next=p2;
p1=p2->next;p2=r;
}
}
};