142.环形链表2:快慢指针

LeetCode.142 环形链表2 (Medium)

这里分享一个LeetCode上的:图解,非常便于理解。

该题是基于环形链表:判断是否有环,并找到环的具体位置(返回环开始的节点)。同时本题需要一点数学和图像上的推导,来证明某一个点就是环起始的位置


第一步和环形链表一样,先通过快慢指针判断是否有环,并找到快慢指针相遇的位置。


此时假设:慢指针走了k步。则:快指针走了2k步,快指针走过的距离减去慢指针走过的距离是k步,即为环周长的整数倍。
此时假设:快慢指针相遇点距离环起始位置的距离mhead到环起始点的距离为k-m
此时快指针走到环起始点的距离也为k-m,这里并未限定是从相遇点到起始点的最短路径,因为已经考虑到了套圈的可能性。因而只需让快指针和慢指针以相同的速度(每次前进1个节点),并且slow重新从head开始,都走k-m的距离,即可相遇,相遇的点即为环的起点。

public class Solution {
    // 题目要求,返回环的位置
    public ListNode detectCycle(ListNode head) {
        // 还是快慢指针那一套,先确定有没有环
        ListNode slow = head, fast = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if (slow == fast) break; // 相遇,有环
        }
        // 确定是:1.有环break 2.没环while结束
        if (fast == null || fast.next == null) return null;
        // 排除无环情况
        // 假设此时,slow指针走了k步到达相遇点,则fast指针走了2k步
        // fast - slow走过的距离 = 2k - k = k,即为环的周长的n倍(n >= 1);k = 环周长的整数倍
        // 假设相遇点距离环开始的地方的距离为m(劣弧距离)
        // 则head到环起点的距离为 k - m
        // 此时让slow重新回到head,fast和slow以相同的速度前进,当他们都前进k-m的距离时即会相遇,这个地方就是环的起点位置
        slow = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值