思路:快慢指针。
假设,环外节点个数是a,环内节点个数是b。
当快指针和慢指针相遇的时候,慢指针走过s步,快指针走过f步
‘ 且 f = 2s (条件1)
走到环入口的节点位置需要t步,那么
t = a + nb (n >= 0) 条件2
并且快慢指针第一次相遇的时候,快指针比慢指针多走了n个环。
即 f - s = nb 条件3
由1和3 得到 s = nb (条件4) 理解为相遇的时候 慢指针走了nb的距离。
由条件2和条件4得到,在相遇点慢指针再走a步,即可以到达环入口处。
所以只要一个相同的慢指针再从起点出发,两个慢指针即可相遇,相遇的点就是环入口。
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null)
return null;
if(head.next == null)
return null;
ListNode fasthead = head;
ListNode slowhead = head;
do {
slowhead = slowhead.next;
if(fasthead == null || fasthead.next == null) {
return null;
}
fasthead = fasthead.next.next;
} while(fasthead != slowhead);
ListNode newSlowhead = head;
while(newSlowhead != slowhead) {
newSlowhead = newSlowhead.next;
slowhead = slowhead.next;
}
return slowhead;
}
}