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}
.
题目的意思是要求对一个链表进行重新排序,如上面所示将 L0→L1→…→Ln-1→Ln, 重新排序之后变成 L0→Ln→L1→Ln-1→L2→Ln-2→…
思路: 可以看成是两个链表进行合并,现拆分 L0→Ln→L1→Ln-1→L2→Ln-2→… 变成:
L0 L1 L2 .......
Ln Ln-1 Ln-2 .....
所以我们可以将 L0→L1→…→Ln-1→Ln, 折半拆分,变成 L0 L1 L2 .....Ln/2 和 Ln/2 Ln/2+1 ....Ln
然后将后半部分进行逆置 ,变成L0 L1 L2 .......,Ln Ln-1 Ln-2 ..... 再将两链表合并
拆分过程在链表归并排序中曾遇到过 Sort List ,定义一快一慢指针,快的一次走两步,慢的一次走一步,遍历链表,最后慢的 的下一个节点为后半部分。
代码如下:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode * reorderList(ListNode *head) { if(head==NULL||head->next==NULL||head->next->next==NULL) return head; ListNode *fast,*showl;//定义fast和showl用来找到链表的中点 fast=head; showl=head; while(fast->next!=NULL&&fast->next->next!=NULL) { fast=fast->next->next;//fast一次走两步 showl=showl->next;//showl 一次走一步 } // ListNode *halfafter=new ListNode() ListNode *start,*pur,*q; start=showl->next;//start表示 下一半节点的开始 //将以start开始的后半节点逆置 pur=start; while(start!=NULL) { q=start; start=start->next; q->next=showl->next; showl->next=q; } pur->next=NULL; ListNode *p,*qur; p=head; //前半部分第一个节点 q=showl->next; //后半部分第一个节点 showl->next=NULL;//断开链表 while(q!=NULL) { pur=p->next; //用来保存前半部分的下一个节点 qur=q->next; //用来保存后半部分的下一个节点 p->next=q; q->next=pur; p=pur; q=qur; } return head; } };
原文地址:http://blog.csdn.net/yujin753/article/details/41988849