找出环形链表的入环点

题目描述:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 说明:不允许修改给定的链表

示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点
在这里插入图片描述

示例 2:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环
在这里插入图片描述

在这里插入图片描述

/**
 * 思路:设从开始到入环点的距离为 x,从入环点到相遇点的距离为 y,整个环的周长为 c。
 *       有两个指针同时从起点走,一个为 s,一个为 f,则相遇时,
 *       s 走的距离:
 *       s = x + y + n1 * c(n1 为正整数)
 *       f 走的距离:
 *       f = x + y + n2 * c(n2 为正整数)
 *       则有:
 *       f - s = (n2 - n1) * c
 *
 *       现在我们假设:
 *       s 的速度为 1,f 的速度为 2,n = n2 - n1
 *       由 f - s = (n2 - n1) * c  ===> f - s = nc
 *       我们知道,两个指针的走的路程、速度不同,但都是从头开始,走到相遇点,时间相同
 *       已知 s 的速度为 1 ===> 时间为 s
 *       则此时 f = 2s(f 速度是 2,时间是 s)
 *       由之前推出的 f - s = nc ===> s + nc = f = 2s ===> s = nc(s 走了 nc 距离)
 *       
 *       我们知道,要到入环点,从开始走 x 距离可以,从开始走 x + nc 距离也可以
 *       
 *       所以,要找到入环点,只需要另外一个指针走 x 距离,而相遇的时候 s 已经走了 nc,
 *       所以 s 再走 x 距离,就会和另外一个指针相遇,此相遇点就是入环点
 *       
 *       注意:理论上,也可以让 f 走 x 距离,但是我们知道 s 的速度是 1,相对来说比 f 更容易些
 *       所以我们选用 s
 */
 public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        //用 do...while 因为最开始 fast == slow,必须让 fast 先走两步,slow 再开始走
        do{
            if(fast==null){
                return null;
            }
            if(fast.next==null){
                return null;
            }
            fast = fast.next.next;
            slow = slow.next;
        }while(fast!=slow);
        //fast 和 slow 相遇
        ListNode p = head;
        while(p!=slow){
            p = p.next;
            slow = slow.next;
        }
        return p;//return slow; 也可以
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值