Linked List Cycle leetcode II java (尋找鏈表環的入口)


題目

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      }


免責聲明!

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



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