题目:
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given{1,2,3,4}, reorder it to{1,4,2,3}.
思路:
(1)用快慢指针寻找中间节点
(2)对后面的链表逆置
(3)将两个链表合并
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *FindMiddle(ListNode *head){//用快慢指针寻找中间节点(前面比后面长)
ListNode *slow = head;
ListNode *quick = head;
while(quick->next != NULL && quick->next->next != NULL){
quick = quick->next->next;
slow = slow->next;
}
return slow;
}
void reverseList(ListNode* & head){//反转链表
ListNode *pre = head;//保存第一个结点
ListNode *p = head->next;//从第二个元素开始,更新它的next指针域
ListNode *ne = NULL;//保存要修改元素的下一个节点
while(p != NULL){
pre->next = p->next;//每次跟新第一个元素的next指针域,最后反转成功后为NULL
ne = p->next;
p->next = head;//跟新next指针域,每次指向前一个元素
head = p;//头指针依次向后移动,最后反转成功指向最后一个元素
p = ne;
}
}
void MergeList(ListNode *&head,ListNode *& middle){//合并两个链表
ListNode *p1 = head, *p2 = middle, *temp = NULL;
while(p2 != NULL){
temp = p2->next;
p2->next = p1->next;
p1->next = p2;
p2 = temp;
p1 = p1->next->next;
}
}
void reorderList(ListNode *head) {
if(head==NULL || head->next==NULL)
return ;
ListNode *middle = FindMiddle(head);
ListNode *p = middle;
middle = middle->next;
p->next = NULL;
reverseList(middle);
MergeList(head,middle);
}
};