LeetCode 142. Linked List Cycle II

原题链接在这里:https://leetcode.com/problems/linked-list-cycle-ii/

题目:

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

Note: Do not modify the linked list.

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

题解:

类似Linked List Cycle.

首先找到是否有cycle,若是没有返回null.

若是有cycle, 那么设a是head 到 cycle start 的距离,b是cycle start 到相遇点的距离,c是cycle的周长,s是walker现在走过的step数。

  1. a + b + mc = s
  2. a + b + nc = 2s

合并上面公式得到 a+b = (n-2m)*c. 也就是说a和b是关于 c 互补的, a+b一定是 c的倍数, 那么从现在的b点往前走a步一定是走了c的倍数回到cycle start点.

可以把walker放回head,runner从b点,两个pointer 都一次向前走一步,走过a步之后恰巧都走到了cycle start.

Time Complexity: O(n). Space: O(1).

AC Java:

 1 /**
 2  * Definition for singly-linked list.
 3  * class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     public ListNode detectCycle(ListNode head) {
14         if(head == null || head.next == null){
15             return null;
16         }
17         ListNode walker = head;
18         ListNode runner = head;
19         while(runner.next != null && runner.next.next != null){
20             walker = walker.next;
21             runner = runner.next.next;
22             if(walker == runner){
23                 walker = head;
24                 while(walker != runner){
25                     walker = walker.next;
26                     runner = runner.next;
27                 }
28                 return walker;
29             }
30         }
31         return null;
32     }
33 }

AC C++:

 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     ListNode *detectCycle(ListNode *head) {
12         if(!head || !head->next){
13             return NULL;
14         }
15 
16         ListNode *runner = head;
17         ListNode *walker = head;
18         while(runner && runner->next){
19             runner = runner->next->next;
20             walker = walker->next;
21             if(runner == walker){
22                 walker = head;
23                 while(walker != runner){
24                     runner = runner->next;
25                     walker = walker->next;
26                 }
27 
28                 return walker;
29             }
30         }
31 
32         return NULL;
33     }
34 };

跟上Find the Duplicate Number.

参见了这篇帖子,是数学想法。

posted @ 2015-09-01 03:45  Dylan_Java_NYC  阅读(295)  评论(0编辑  收藏  举报