zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    浅析WPhone、Android的Back与Home键
    Android音频播放之SoundPool
    Button、ImageButton及ImageView详解
    文本 To 音频
    gravity、layout_gravity及orientation
    项目规范性检测工具Lint
    Android视频播放之VideoView
    ContentProvider数据访问详解
    QQ第三方登录
    Android数据共享
  • 原文地址:https://www.cnblogs.com/fuzzier/p/9165838.html
Copyright © 2011-2022 走看看