Given a linked list, return the node where the cycle begins.
If there is no cycle, return null.
Example
Given -21->10->4->5, tail connects to node index 1,return 10
Challenge
Follow up:
Can you solve it without using extra space?
思路
先用Linked List Cycle这题的解题思路来找有没有环。
如果有环,我们从快慢指针重合的位置,以及从链表的头,开始每次走一步,一直走到这两个指针重合,就是我们要找的环的入口。
用个不严格的推导:
假设上面这个例子,slow指针从1走到3要走x,从3走到和fast指针重合要再走y,这个环的长度是r。
假设fast多走1圈就可以和slow重合,那么重合的时候slow走了x + y,fast走了x + r + y。
我们知道fast走了slow的两倍,也就是2x + 2y。
所以2x + 2y = x + y + r
==> r - y = x
从slow和fast的重合点,再走到环的入口,我们知道需要r - y,也就是上面结论里的x。这说明slow和fast的重合点到环的距离,和链表头到环的距离是一样的。
Code
/** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { * this.val = val; * this.next = null; * } * } */ public class Solution { /** * @param head: The first node of linked list. * @return: The node where the cycle begins. * if there is no cycle, return null */ public ListNode detectCycle(ListNode head) { // write your code here if (head == null || head.next == null) { return null; } ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (slow == fast) { while (head != slow) { head = head.next; slow = slow.next; } return head; } } return null; } }