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?
题解:
首先找到是否有cycle,若是没有返回null.
若是有cycle, 那么设a是head 到 cycle start 的距离,b是cycle start 到相遇点的距离,c是cycle的周长,s是walker现在走过的step数。
- a + b + mc = s
- 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 };
参见了这篇帖子,是数学想法。