1 判断ListNode中是否存在cycle
使用快慢指针即可
2 判断cycle的长度
一个指针不动,另一个指针走一圈
3 判断cycle起点
图片来自 https://www.cnblogs.com/TIMHY/p/8280725.html
假设链表起点到圈起点的距离为x;圈起点到快慢指针相遇点的距离为y;r为圈的周长;慢指针总共走的距离为l,那么快指针则为2l。
所以 l = x + ar + y (1)
2l = x +br + y (2)
所以 式(2) - 式(1) 为 l = (b-a)r (3) 慢指针相当于走了n倍的圈
所以 由式(1)和式(3)可得 br = x + y (4)
所以 x = br - y 式(5) 证明完毕
令一个指针在链表起点处,一个指针在圈的起点处,两个指针同时走一步
所以当一个指针走到圈的起点(x),另一个指针也走了x,也就是br-圈的起点到相遇点距离(y),二者相遇再次也就是圈的起点。
代码
# Definition for singly-linked list. class ListNode(object): def __init__(self, x): self.val = x self.next = None class FloydCycle(object): def detecting(self, head): # params: head: type is ListNode fast, slow = head, head # judge cycle while fast and fast.next: fast = fast.next.next slow = slow.next if fast == slow: print 'Have cycle' break print 'Have not cycle' # premise have cycle # judge cycle length count = 0 while slow: slow = slow.next count += 1 if slow == fast: print 'Length is %d' % count break # judge cycle startPoint fast2 = head # step is 1 while fast2 != slow: fast2 = fast2.next slow = slow.next print slow