快慢指针:141. 环形链表(判断是否存在环路)

题目描述

给定一个链表,判断链表中是否有环

题目链接

141. 环形链表

解题思路

使用快慢指针(Floyd判圈算法):从链表的头部设置两个指针,p1的步长为1, p2的步长为2,同时向前走,如果p1和p2最终能够相遇,则说明链表是有环的。

检测环的基本思想是非常简单的,可以类比成两个人在跑道上跑。只要有圈,跑的快的那个人就一定能够追上跑得慢的那个人。

代码:

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null) {
            return false;
        }   
        //设置快慢指针
        ListNode slow = head, fast = head.next;
        while(slow!=null&&fast!=null&&fast.next!=null){
            if(slow == fast){
                return true;
            }
            slow = slow.next;
            fast = fast.next.next;
        }
        return false;
    }
}

扩展

  1. 求环的长度

    两个人相遇的是时候,一定已经在环上了,然后两个人只要再次在环上接着跑,再次相遇的时候(也就是所谓的套圈),跑的快的那个人就比跑得慢的人整整多跑了一圈,所以环的长度也就出来了。

    用算法来描述:第一次相遇后,p1和p2按照原来的步长继续向前查找,并且记录下两个指针遍历过的节点个数。当两个指针再次相遇的时候,遍历的节点数量差就是环的长度。

  2. 求环的起点

    解决方法
    把其中的一个指针重置到链表头部,然后两个指针步长都为1,继续向前移动,相遇的位置即为环的起点。

    解释:
    首先我们设第一次相遇的时候慢指针走过的节点个数为i, 设链表头部到环的起点的长度为m, 环的长度为n,相遇的位 置与起点位置距离为k
    则可以得到:
    i = m + a * n + k

    其中a为慢指针走的圈数。
    根据快指针和慢指针的速度关系,我们可以得到另一个式子:
    2 * i = m + b * n + k

    其中b为快指针走的圈数。
    简单处理得到:
    i = (b - a) * n

    也就是说i是圈长的整数倍。
    这时将其中一个节点放到起点,然后同时向前走m步时,此时从头部走的指针在m位置。而从相遇位置开始走的指针应该在距离起点i + m, i为圈长整数倍,则该指针也应该在距离起点为m的位置,即环的起点。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值