如何求单链表的环入口点 - 龟兔赛跑法 - 动画解释

栏目: 数据库 · 发布时间: 5年前

内容简介:当单向链表中存在环的时候,遍历此链表会发生无限循环,无法到达末尾(入环后链表就不存在末尾了)的情况,所以在可能发生这种情况的时候,需要检查链表中是否存在一个环。检查是链表是否存在环的方法就是「下面的动图解释了这一过程:

当单向链表中存在环的时候,遍历此链表会发生无限循环,无法到达末尾(入环后链表就不存在末尾了)的情况,所以在可能发生这种情况的时候,需要检查链表中是否存在一个环。

检查是链表是否存在环的方法就是「 龟兔赛跑 」法:乌龟和兔子同时从头节点开始遍历链表,兔子遍历的速度大于乌龟的速度,如果链表中存在环,兔子和乌龟就会先后进环,由于兔子的速度比乌龟快,他们必然会在环内相遇。

下面的动图解释了这一过程:

如何求单链表的环入口点 - 龟兔赛跑法 - 动画解释

这个算法的美妙之处在于,乌龟和兔子相遇的地方和环入口点的位置是有关系的。

根据动画所示,我们令兔子的遍历速度为2,乌龟的遍历速度为1,则他们的速度差也为1。设乌龟进环的时候已经遍历了 x x 个节点,那么此时兔子也已经在环内遍历了 x x 个节点。若令环的大小为 y y ,兔子和乌龟在环内的遍历就是一次追及问题,兔子需要追上乌龟的距离为 y x y-x 。由于兔子和乌龟的速度差为1,所以追及时间 t = ( y x ) ÷ 1 = y x t=(y-x)\div1=y-x ,那么乌龟和兔子相遇的点距离环入口也就是 x x 了。此时只需要将兔子放回起点,并把兔子的遍历速度换成1,则乌龟将会和兔子在环入口处再次相遇。

最后附上 Java 算法:

LinkedListNode solve(LinkedListNode head) {
    LinkedListNode rabbit = head;
    LinkedListNode turtle = head;

    while (rabbit != null && rabbit.next != null) {
        rabbit = rabbit.next.next;
        turtle = turtle.next;
        if (rabbit == turtle) break;
    }

    if (rabbit == null || rabbit.next == null) return null;

    rabbit = head;
    while (rabbit != turtle) {
        rabbit = rabbit.next;
        turtle = turtle.next;
    }
    return rabbit;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学建模算法与应用

数学建模算法与应用

司守奎、孙玺菁 / 国防工业出版社 / 2011-8 / 49.00元

《数学建模算法与应用》主要内容简介:作者司守奎、孙玺菁根据多年数学建模竞赛辅导工作的经验编写《数学建模算法与应用》,涵盖了很多同类型书籍较少涉及的新算法和热点技术,主要内容包括时间序列、支持向量机、偏最小二乘面归分析、现代优化算法、数字图像处理、综合评价与决策方法、预测方法以及数学建模经典算法等内容。《数学建模算法与应用》系统全面,各章节相对独立。《数学建模算法与应用》所选案例具有代表性,注重从不......一起来看看 《数学建模算法与应用》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具