zoukankan      html  css  js  c++  java
  • 判断单链表中是否有环,找到环的入口节点的理论证明

    我们把该链表抽象为这样一个模型,假设环长为nn

    情景1 
    此处输入图片的描述 
    此图表示其实状态,其中hh表示链表头节点,slow,fastslow,fast,起始状态指向hhtt表示环的入口节点。

    情景2 
    此处输入图片的描述 
    此图表示slowslow运动到了ttfastfast运动到m1m1,节点hh和节点tt之间的距离为aa,节点tt和节点m1m1之间的距离(弧长)为bb,并设此时fastfast在环上做了rr次圆周运动(因为aann的长度都不固定,多以fastfast可能已经在环上运动了好多圈了)。相对于slowslow其运动的距离为:aa由于fastfast速度是slowslow的二倍,所以其运动的距离(步数)为:2a2a 
    并且,经过观察可知fastfast运动的距离为:a+nr+ba+nr+b,所以可知公式①: 

    a=nr+ba=nr+b

    情景3. 
    此处输入图片的描述 
    此时,slow,fastslow,fast相遇在节点m2m2,也就是代码中1010行判断成立的地方。其中m2m2为相遇点,bb还是为弧长。由于链表的指针是有方向的,我们约定在环上计算距离的时候按照逆时针计算,也就是说,从ttm1m1的距离为bb,从m1m1tt的距离为nbn−b(其中nn为环的长度)。 
    同理在情况2中,从fastfastslowslow的距离为nbn−b,它们的速度差为11,所以它们再次相遇的时候经过的时间为nb1=nbn−b1=n−b,slowslow经过的距离为(nb)×1=nb(n−b)×1=n−b,所以假设相遇点为m2m2,那么显而m2m2tt的距离为bb

    情景4. 
    此处输入图片的描述 
    情况4对应着代码中的1111~1919行。因为通过上面的讨论,如果能让qq向前运动:b+xnb+xn步,那么qq的位置恰好是tt,其中x{0,1,2,3,}x∈{0,1,2,3,⋅⋅⋅}。 
    值得高兴的是,在情况2中我们有公式①,观察到aa恰好符合这样一个步数值,所以我们让p=hp=hp,qp,q,都每次向前移动11,当他们相遇的时候恰好就是环的入点tt,也就是说pphh移动到pqp,q再次相遇在这里的作用是提供一个计数。 
    所以,当ppqq再次相遇的时候,他们的相遇点恰好了tt,也就是需要找的环的入口点。

    复杂度

    我们关注第一次循环的slowslow和第二次循环的pp,因为它们都是每次前进一步,由它们移动的步数,可以得到算法的时间复杂度,所以易知时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)

  • 相关阅读:
    视频直播:Windows中各类画面源的截取和合成方法总结
    短视频技术详解:Android端的短视频开发技术
    视频直播关键技术:流畅、拥塞和延时追赶
    视频直播技术详解:直播的推流调度
    直播技术:从性能参数到业务大数据,浅谈直播CDN服务监控
    音视频通话:小议音频处理与压缩技术
    pip命令报错“no perl script found in input”
    python常见面试题讲解(三)明明的随机数
    如何使用photoshop修改图片的像素大小(分辨率)
    VMware Workstation如何修改弹出释放快捷键
  • 原文地址:https://www.cnblogs.com/muyangshaonian/p/9650479.html
Copyright © 2011-2022 走看看