142. Linked List Cycle II - Medium
Given a linked list, return the node where the cycle begins. If there is no cycle, return null
.
To represent a cycle in the given linked list, we use an integer pos
which represents the position (0-indexed) in the linked list where tail connects to. If pos
is -1
, then there is no cycle in the linked list.
Note: Do not modify the linked list.
Example 1:
Input: head = [3,2,0,-4], pos = 1 Output: tail connects to node index 1 Explanation: There is a cycle in the linked list, where tail connects to the second node.
Example 2:
Input: head = [1,2], pos = 0 Output: tail connects to node index 0 Explanation: There is a cycle in the linked list, where tail connects to the first node.
Example 3:
Input: head = [1], pos = -1 Output: no cycle Explanation: There is no cycle in the linked list.
Follow up:
Can you solve it without using extra space?
Floyd's cycle detection algorithm, aka Tortoise and Hare Algorithm
ref: http://fisherlei.blogspot.com/2013/11/leetcode-linked-list-cycle-ii-solution.html
假设cycle前的长度为X,cycle的长度为Y,快慢指针分别走过 2t 和 t 的路程后,相遇在K点,那么:
慢指针 t = X + nY + K (1)
快指针 2t = X + mY+ K (2) m,n为未知数
(1) 代入到 (2) 中, 有 2X + 2nY + 2K = X + mY + K => X+K = (m-2n)Y (3)
这说明,X和K的关系是基于Y互补的,即两个指针相遇以后,再往下走X步就回到Cycle的起点了
time: O(n), space: O(1)
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode detectCycle(ListNode head) { ListNode slow = head, fast = head, start = head; while(fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if(fast == slow) { while(slow != start) { slow = slow.next; start = start.next; } return start; } } return null; } }