Linked List Cycle leetcode II java (尋找連結串列環的入口)

愛做飯的小瑩子發表於2014-07-23

題目

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Follow up:
Can you solve it without using extra space?

 

題解

這個連同I都是很經典的題啦,刷CC150時候就折磨了半天。

其實就推幾個遞推公式就好。。首先看圖(圖引用自CC150):


從連結串列起始處到環入口長度為:a,從環入口到Faster和Slower相遇點長度為:x,整個環長為:c。

明確了以上資訊,就可以開始做運算了。。

 

 假設從開始到相遇,Slower走過的路程長為s,由於Faster的步速是Slower的2倍,那麼Faster在這段時間走的路程長為2s。

 而對於Faster來說,他走的路程還等於之前繞整個環跑的n圈的路程nc,加上最後這一次遇見Slower的路程s。

 所以我們有:

                   2s = nc + s

 對於Slower來說,他走的路程長度s還等於他從連結串列起始處到相遇點的距離,所以有:

                    s = a + x 

 通過以上兩個式子代入化簡有:

                    a + x = nc

                    a = nc - x

                    a = (n-1)c + c-x

                    a = kc + (c-x)

那麼可以看出,c-x,就是從相遇點繼續走回到環入口的距離。上面整個式子可以看出,如果此時有個pointer1從起始點出發並且同時還有個pointer2從相遇點出發繼續往前走(都只邁一步),那麼繞過k圈以後, pointer2會和pointer1在環入口相遇。這樣,換入口就找到了。

Reference: http://blog.csdn.net/xiaxia__/article/details/19356861

 

程式碼如下:

 1     public ListNode detectCycle(ListNode head) {
 2         if(head==null||head.next==null)
 3             return null;
 4         
 5         ListNode fast = head,slow=head;
 6         while (true) {
 7             if (fast == null || fast.next == null) {
 8             return null;   
 9         }
10             slow = slow.next;
11             fast = fast.next.next;
12             
13             if(fast==slow)
14                 break;
15         }
16         
17         slow = head;//slow back to start point
18         while(slow != fast){
19             slow = slow.next;
20             fast = fast.next;
21         }
22         return slow; //when slow == fast, it is where cycle begins
23     }

相關文章