[Leetcode] Reorder list 重排鏈表


Given a singly linked list LL 0→L 1→…→L n-1→L n,
reorder it to: L 0→L n →L 1→L n-1→L 2→L n-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}.

反轉以后的鏈表是,從左往右是,node0->noden->node1->nodenn-1->.....,首先想到是將鏈表L按照這個規律重新賦值一遍,但題中說不能改變結點的值;然后想到將鏈表反轉然后重新連接起來,如1->2->3->4,

按虛線那樣走,形成1->4->2->3->3->2->4->1,若是結點的值都不相同,則遇到相同時,就可以斷開形成,若是有相同,可先統計結點的個數,然后判斷終止條件。這樣就需要新建一個鏈表。所以想到將鏈表一分為二,反轉后半段,然后重新連接起來,依舊是1->2->3->4,

這樣思路就出來了,分三步走,第一步,將鏈表一分為二,用到快慢指針;第二步,反轉第二部分,反轉鏈表是很重要的根基;第三步,將兩鏈表接起來。參考了JustDoIt的博客。

使用快慢指針將鏈表分成兩段,采用這種方式會導致在鏈表結點個數為奇數的情況下,后半段的個數比前半段多一個。前半段一preSlow維結束,后半段一slow開始。所以在第三步將兩子鏈表連接起來的時候,要注意判斷反轉以后以newBeg開始的后半段是否已經結束,沒有,則連接上剩余部分即可。

針對反轉鏈表,要認真的理解,關鍵是反轉以后,要在新的鏈表結尾加上next=NULL。

 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     {
13         if(head==NULL||head->next==NULL)
14             return;
15         //分成兩段
16         ListNode *preSlow=NULL;
17         ListNode *slow=head,*fast=head;
18         while(fast&&fast->next)
19         {
20             preSlow=slow;
21             slow=slow->next;
22             fast=fast->next->next;
23         }  
24         preSlow->next=NULL; //前半段
25 
26         //反轉后半段
27         ListNode *newBeg=slow;
28         ListNode *last=newBeg->next;
29         while(last)
30         {
31             ListNode *temp=last->next;
32             last->next=newBeg;
33             newBeg=last;
34             last=temp;
35         }
36         slow->next=NULL;
37 
38         //合並
39         fast=head;
40         preSlow=NULL;
41         while(fast) //注:以前半段為條件
42         {
43             ListNode *tem=newBeg->next;
44             newBeg->next=fast->next;
45             fast->next=newBeg;
46             fast=newBeg->next;
47             preSlow=newBeg;
48             newBeg=tem;
49         }
50         if(newBeg !=NULL)   //因節點個數為奇數時,后段比前段多一個,所以最后要判斷
51             preSlow->next=newBeg;
52     }
53 };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM