Leetcode——142. 环形链表 II

概述

142. 环形链表 II

分析

  • 技巧类的题目

  • 该题可以分为两步:

    1. 确定链表是否有环; —> 快慢指针法

    2. 确定环的起始结点

      (x+y)*2=(x+y)+n(y+z)		//这里n(y+z)是快指针多走的,n代表多做圈数
      x=n(y+z)-y=(n-1)(y+z)+z	//x是我们要求的
      注意到(n-1)(y+z)是环的长度,也就是说,x的长度 = 从指针相遇位置开始的n-1圈 + z
      那么 一个指针A从头结点开始,一个指针B从相遇结点开始,同时移动,A会一直向前,B会在环内一直转圈
      但是当A走了(n-1)*(y+z)后,B因为环的原因会回到起始位置,此时A、B均还剩z的长度到入口结点,这样当A、Bx
      

思路

为何慢指针第一圈走不完一定会和快指针相遇?

  • 可以认为快指针和慢指针是相对运动的,假设慢指针的速度是 1节点/秒,快指针的速度是 2节点/秒,当以慢指针为参考系的话(即慢指针静止),快指针的移动速度就是 1节点/秒,所以肯定会相遇。

为什么在第一圈就会相遇呢?

  • 设环的长度为 L,当慢指针刚进入环时,慢指针需要走 L 步(即 L 秒)才能走完一圈,此时快指针距离慢指针的最大距离为 L-1,我们再次以慢指针为参考系,如上所说,快指针在按照1节点/秒的速度在追赶慢指针,所以肯定能在 L 秒内追赶到慢指针。

代码

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow = head, *fast = head;
        do{
            if (!fast || !fast->next)    return nullptr;     // 无环
            fast = fast->next->next;   	// 快指针,一次移动      
            slow = slow->next;
        }while(slow != fast);

        slow = head;
        while(slow != fast) {
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值