2. 解题思路
- 找到中间节点,从中间节点位置断开,得到两个链表
- 对链表的后半截部分进行翻转
- 将前半截和翻转后的后半截链表进行合并
3. 算法
- 通过slow、fast指针找到链表的中间位置
- 对后半截链表进行翻转操作(注意:后半截链表从ceil(n/2)+1位置开始,ceil表示向上取整,整个链表从1开始)
- 对两个链表进行合并,因为进行了向上取整,所以前半截链表的长度大于等于后半截链表
4. 实现
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
void reorderList(ListNode* head) {
if(head == NULL || head->next == NULL) return;
//通过slow、fast指针找到链表的中间位置
ListNode *slow = head, *fast = head;
while(fast != NULL && fast->next != NULL && fast->next->next != NULL){
slow = slow->next;
fast = fast->next->next;
}
//对后半截链表进行翻转操作
//注意:后半截链表从ceil(n/2)+1位置开始,ceil表示向上取整,整个链表从1开始
ListNode *sub_head = slow->next;
sub_head = reverseList(sub_head);
//对两个链表进行合并,因为进行了向上取整,所以前半截链表的长度大于等于后半截链表
slow->next = NULL;
ListNode *new_head = head;
while(sub_head != NULL){
ListNode *sub_next = sub_head->next;
ListNode *new_next = new_head->next;
sub_head->next = new_head->next;
new_head->next = sub_head;
sub_head = sub_next;
new_head = new_next;
}
}
private:
ListNode* reverseList(ListNode* head){
if(head == NULL || head->next == NULL) return head;
ListNode *n = head->next;
ListNode *new_head = reverseList(head->next);
head->next = n->next;
n->next = head;
return new_head;
}
};