143.重排链表
思路:
链表分成前后两部分,后半部分反转,再一起穿插放入新链表
1.遍历链表找链表的终点(快慢指针)
2.从slow结点分出后半部分再reverse,slow->next是新的头
3.双指针遍历两个链表
class Solution {
public:
void reorderList(ListNode* head) {
//快慢指针找中点
ListNode* fast=head;
ListNode* slow=head;
while(fast->next!=nullptr&&fast->next->next!=nullptr){
fast=fast->next->next;
slow=slow->next;
}
//偶数平均分,奇数中点算前半部分
ListNode* newHead=reverse(slow->next);
slow->next=nullptr;//前半段链表收尾
//此时的head是前半段链表,相当于往里插入后半段倒序
ListNode* p=head;
ListNode* q=newHead;
while(p!=nullptr&&q!=nullptr){
//合并链表
ListNode* tmp1=p->next;
ListNode* tmp2=q->next;
p->next=q;
p=tmp1;
q->next=p;
q=tmp2;
}
}
//反转链表
ListNode* reverse(ListNode* head){
ListNode* cur=head;
ListNode* pre=nullptr;
while(cur!=nullptr){
ListNode* tmp=cur->next;
cur->next=pre;
pre=cur;
cur=tmp;
}
return pre;
}
};