Floyd判圈法

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
原文地址:https://www.cnblogs.com/fuzzier/p/9165838.html