题目链接:linked-list-cycle-ii
/**
*
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?
*
*/
public class LinkedListCycleII {
// 16 / 16 test cases passed.
// Status: Accepted
// Runtime: 214 ms
// Submitted: 29 minutes ago
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
//解题思路:
//设置两个指针,slow每走一步,fast走两步
//如果有环,则在环内某点相遇,此时slow走的距离为 d, fast走的距离为 2d
//当其相遇时,fast指针已经在环内走了 n 圈
//设环的长度为R
//故对于 fast指针 2d = d + n * R
//可知 d = n * R
//设入口点到相遇点的距离为 x
//则头指针到入口点的距离为 d - x
//我们可以向后推一下,如果 fast少走x步,那是不是就是环的入口点
//即 d - x = n * R - x
//那么可以在fast和slow相遇后,从头指针设置一个新的指针 p
// p 和slow 同步前进
//当p走了 d - x 步时, slow 走了 n * R - x步时,在环入口点相遇
//时间复杂度O(n) ,空间复杂度 O(1)
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if(slow == fast) {
ListNode p = head;
while(slow != p) {
slow = slow.next;
p = p.next;
}
return p;
}
}
return null;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}