zoukankan      html  css  js  c++  java
  • 判断链表是否有环及环入口点的求法

    首先,判断一个单链表是否有环。网上有很多解法就是设置两个指针fast,slow分别指向链表头部,然后同时向后遍历。fast步长为2即每次走两步,slow每次走一步。如果fast走到链表尾部则肯定没有环,因为如果有环肯定是如下图所示的样子。

    如果fast和slow相遇则有环。有没有可能在有环的情况下fast和slow永远不相遇呢?假设在某个时间slow走过的路程为S而且slow已经在环上了,则fast走过的为2S。因为fast是速度是slow的两倍。假设环的长度为L,fast和slow不相遇的条件就是(2S - S) % L != 0永远成立,因为fast和slow相遇即在某一时刻fast比slow多走过了n(n>=1)圈,(2S - S) % L == S % L != 0是不是会永远成立?明显不会,因为S每次增加1,总有一天会等于0成立。

    现在假设已经知道了有环,来求环的入口点。

    如上图所示,我们先作如下的假设:

    链表起点为A点;

    环的入口为B点;

    fast和slow的相遇点为C;

    链表的方向为顺时针;

    A到B的距离为X;

    B到C的距离为Z;

    C到B的距离为Y。

    则有如下的结果成立:

    1. X + Z = S;

    2. X + Z + nL = 2S;

    3. Y + Z = L;

    即X + Z + nL = 2X + 2Z -> X = nL - Z = nL - (L - Y) = (n - 1)L + Y。最后的结果就是X = (n - 1)L + Y,其中n>=1。也就是说从A和C点同时出发,以步长为1遍历链表,那么在C处出发的指针在多走了n-1圈之后与从A出发的指针在B处相遇。也就是说两个指针指向同一个节点的时候这个点就是环的入口点。

  • 相关阅读:
    python基础-网络编程part01
    常见的加密算法
    mvn常用命令
    Stream排序Map集合
    解决浮点运算精度不准确,BigDecimal 加减乘除
    阿里fastjson解析
    java可变参数
    set集合迭代
    包装类型间的相等判断
    java集合与数组之间转换
  • 原文地址:https://www.cnblogs.com/likeio/p/3593686.html
Copyright © 2011-2022 走看看