描述
给定一个单链表L:L0->L1->....->Ln-1->Ln,重新排列链表为这样的顺序:L0->Ln->L1->Ln-1....
使用原地操作,不可以修改节点的值;
分析
这道题目可以分为三部分:
1,找到单链表的中间节点,从此断开,将链表分为前、后两部分;
2,将后半部分单链表逆转;
3,将前后两个链表合并;
实现
//Reorder List
ListNode *reorderList(ListNode *head)
{
ListNode *middle = findTheMiddleNode(head);
ListNode *list2 = middle->next;
ListNode *cur = head;
middle->next = nullptr;
// 逆转list2
list2 = reverseWithHeadNode(list2);
//依次插入list1 list2
while (cur->next) {
ListNode *next1 = cur->next;
cur->next = list2;
list2 = list2->next;
cur->next->next = next1;
cur = next1;
}
cur->next = list2;
return head;
}
// Find the middle node
ListNode *findTheMiddleNode(ListNode *head)
{
ListNode *slow = head;
ListNode *fast = head;
ListNode *middle = nullptr;
while (fast && fast->next) {
middle = slow;
slow = slow->next;
fast = fast->next->next;
}
return middle;
}
// reverse just with head node
ListNode *reverseWithHeadNode(ListNode *head)
{
ListNode *prev = head;
ListNode *cur = head->next;
ListNode *next = cur->next;
while (cur) {
cur->next = prev;
//移动指针
prev = cur;
cur = next;
next = next?next->next:nullptr;
}
head->next = nullptr;
return prev;
}
此算法的时间复杂度为O(n),空间复杂度为O(1)。