编程导航算法通关村 第一关|黄金挑战通关文牒/java:关于判断链表是否有环,并找出入口

链表是否有环是一个经典问题,那么它到底是怎么判断的呢如图

链表环的入口是可以通过数学验证得出:

        1:我们假设有两个快慢指针,快指针一下走两个,慢指针一下走一个,那么快指针必定先到环中,在慢指针到入口的时候,快指针已经走了n个环+到了环内某个位置  从这之后 快慢指针都在环中,并且快指针必将在慢指针走一圈之内与慢指针重合,因为快慢指针的相对速度为1,慢指针走1圈,快指针就会相对慢指针走1圈,所以快慢指针必在慢指针走一圈之内重合

2,当慢指针到了入口的地方 我们假设  快慢指针在如下重合,入口到重合位置长度为n,重合位置到入口处为z,环长度为y,从链表开头到入口为x ,y=n+z;

3 以上所述可以导出一个公式

慢指针所走的等于长指针走的

x:链表开头到入口

y:环长度 =(n+z)

n:环入口到重合位置

z:重合位置到入口

m:慢指针到入口时快指针走的环圈数

2(x+n)=x+n+m(n+z)

x+n=m(n+z)

x+n=(m-1)(n+z) 

x=(m-1)(n+z)+z

(m-1)(n+z)就是快指针走的圈数减一圈,不影响它们的关系

当(m-1)(n+z)=0时,可以看出x=z

综上可以得知,如果有环的话,快慢必定相遇并且重合位置距离入口的长度等于从链表开头到入口的长度

那么代码就好实现了下面的java的代码

  public static ListNode Ring(ListNode root) {
        if (root == null) {
            return null;
        }
        ListNode l = root;
        ListNode r = root;
        while (r != null && r.next != null) {   //为啥判断r 是因为r是快指针如果不存在环,快指针直接结束循环
            r = r.next.next;       //快慢指针迭代
            l = l.next;
            if (r == l) {       //判断重合位置
                r = root;       //此时快指针回到链表开头
                while (true) {   //快慢指针速度变为一致开始遍历查找入口
                    if (r == l)
                        return r;     //返回入口
                    r = r.next;
                    l = l.next;
                }
            }
        }
        return null;           //无环返回null
    }

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值