Reorder List
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}
.
首先利用快慢指针将链表进行切割,那么左链表为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 };