思路
1、首先利用快慢指针,将链表分成两段。
2、将slow指针对应的后半段链表进行反转(反转链表操作)
3、利用归并排序的思想,合并两个链表。(tips:利用dummy节点可以提高效率)
/*
* @lc app=leetcode.cn id=143 lang=cpp
*
* [143] 重排链表
*/
// @lc code=start
/**
* 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* second){
if(second==nullptr||second->next==nullptr) return second;
ListNode* pre=nullptr;
ListNode* cur=second;
while(cur!=nullptr){
ListNode* temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
return pre;
}
ListNode* mergeList(ListNode* head,ListNode* second){
if(head==nullptr) return second;
if(second==nullptr) return head;
ListNode* pre=new ListNode(0);
ListNode* HEAD=pre;
while(head&&second){
pre->next=head;//串上一个节点
head=head->next;//该节点所在链表向后移一个
pre=pre->next;//pre跟进
pre->next=second;
second=second->next;
pre=pre->next;
}
if(head==nullptr) pre->next=second;
if(second==nullptr) pre->next=head;
return HEAD->next;
}
ListNode* reorderList(ListNode* head) {
if(head==nullptr||head->next==nullptr) return head;
//找到链表中间结点,方法是利用快慢指针
ListNode* slow=head,*fast=head->next;
while(fast!=nullptr&&fast->next!=nullptr){
slow=slow->next;
fast=fast->next->next;
}
ListNode* second=reverseList(slow->next);
slow->next=nullptr;//要把链表切成2段
mergeList(head,second);
return head;
}
};