[链表专题]环形链表 II

描述

本题是力扣的142. 环形链表 II

考点

  • 快慢指针/双指针
  • 链表的环

题解

class Solution {
	public:
		ListNode *detectCycle(ListNode *head) {
			ListNode *slow = head, *fast = head;
			while (fast != nullptr) {
				slow = slow->next;
				fast = fast->next;
				if (fast != nullptr) fast = fast->next;
				if (fast != nullptr && slow == fast) {
					ListNode *slow = head;
					while (slow != fast) {
						slow = slow->next;
						fast = fast->next;
					}
                    //这里换成slow是一样的
					return fast;
				}
			}
			return nullptr;
		}
};

思路

我曾在141. 环形链表的题解中阐述了如何用快慢指针判断链表是否存在环,本题是其升级版,要寻找环的入口

我们已知链表头,能求得相遇点,现在要找到环入口,绘图如下

通式

根据快指针移动速度是慢指针移动速度的两倍这一性质,可以得到以下通式
L + m × C + X 1 ⏟ 慢指针到达相遇点所需时间 = L + n × C + X 2 ⏟ 快指针到达相遇点所需时间 \underset{\text{慢指针到达相遇点所需时间}}{\underbrace{\frac{L+m\times C+X}{1}}}=\underset{\text{快指针到达相遇点所需时间}}{\underbrace{\frac{L+n\times C+X}{2}}} 慢指针到达相遇点所需时间 1L+m×C+X=快指针到达相遇点所需时间 2L+n×C+X
解释如下

L:链表头到环入口的距离

X:环入口到相遇点的距离

C:环的周长

m,n:未知数,各指针绕环次数

两个未知数是无法编程的,可以优化一下

慢指针在环内第一圈就能与快指针重合

慢指针达到环入口时,假设快指针与慢指针的相对距离长度为M

显然,M必小于周长C

根据141. 环形链表的题解中提到的相遇时间公式,能得到下面不等式;代表慢指针在进入环内的第一圈就与快指针相遇了
M 2 − 1 ⏟ 相遇时间 < C = C 1 ⏟ 慢指针绕环一次的时间 \underset{\text{相遇时间}}{\underbrace{\frac{M}{2-1}}}<\underset{\text{慢指针绕环一次的时间}}{\underbrace{C=\frac{C}{1}}} 相遇时间 21M<慢指针绕环一次的时间 C=1C
所以,通式可以优化为
L + X 1 ⏟ 慢指针到达相遇点所需时间 = L + n × C + X 2 ⏟ 快指针到达相遇点所需时间 \underset{\text{慢指针到达相遇点所需时间}}{\underbrace{\frac{L+X}{1}}}=\underset{\text{快指针到达相遇点所需时间}}{\underbrace{\frac{L+n\times C+X}{2}}} 慢指针到达相遇点所需时间 1L+X=快指针到达相遇点所需时间 2L+n×C+X

实现

通式变形,可以得到
2 × ( L + X ) = L + n × C + X 2\times \left( L+X \right) =L+n\times C+X 2×(L+X)=L+n×C+X

L = n × C − X L=n\times C-X L=n×CX

L = ( n − 1 ) × C + ( C − X ) L=\left( n-1 \right) \times C+\left( C-X \right) L=(n1)×C+(CX)

最终通式的含义可以这么理解

某指针A从链表头出发

某指针B同时从相遇点出发,先走过C-X个单位到达环入口,再绕环n-1次

最终两个指针将在环入口相遇

再结合题解的源码看,就一目了然了

更多

恭喜你完成本题!

你可以选择继续下一题,或移步至仓库开始更多类型的挑战:https://fi3wey.github.io/

仓库内包含了更多经典案例的逻辑剖析与实现细节,助你在算法的学习之旅上一往无前!

看官若还满意,还请Star一下哟~

关注公众号峰狂算法,获取最新的刷题指导呀~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值