Reorder List

Given a singly linked list LL0→L1→…→Ln-1→Ln,
reorder it to: L0→LnL1→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}.

 

首先利用快慢指针将链表进行切割,那么左链表为n/2个,右边表为n-n/2个,即如果n为偶数,左右链表节点个数相同,如果n为奇数,那么右链表比左链表节点个数多一个,然后反转右链表,在依次将右链表节点依次插入左链表节点的夹缝中。

例如:链表尾  1   2   3   4    5

      切割后左链表  1   2,右链表 3   4   5,反转右链表  5    4    3

    右链表依次插入到左链表中  1   5   2   4   3

代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     void reorderList(ListNode *head) {
12         if( !head || !head->next || !head->next->next ) return ;    //如果节点个数少于3个,那就不用reorder
13         ListNode* fast = head;
14         ListNode* slow = head;
15         ListNode* pre = 0;
16         while( fast && fast->next ) {   //设立快指针和慢指针,切割链表
17             fast = fast->next->next;
18             pre = slow;
19             slow = slow->next;
20         }
21         ListNode* lhead = head; //左链表n/2个
22         pre->next = 0;
23         ListNode* rhead = reverseList(slow);    //右链表n-n/2个,同时右链表需要反转
24         pre = 0;
25         while( lhead && rhead ) {   //依次将右链表节点插入到左链表中
26             ListNode* p = rhead;
27             rhead = rhead->next;
28             p->next = lhead->next;
29             lhead->next = p;
30             pre = p;    //需要记录lhead在最终链表的前驱
31             lhead = p->next;
32         }
33         pre->next = rhead;  //如果左右链表个数不等,那么右链表必长,直接将右链条剩余节点接在pre后面,此时lhead已为空
34     }
35     
36     ListNode* reverseList(ListNode* head) { //反转链表
37         if( !head ) return 0;
38         ListNode* p = head->next;
39         head->next = 0;
40         while( p ) {
41             ListNode* q = p;
42             p = p->next;
43             q->next = head;
44             head = q;
45         }
46         return head;
47     }
48 };

 

posted on 2014-09-04 10:31  bug睡的略爽  阅读(137)  评论(0编辑  收藏  举报

导航