描述
本题是力扣的141. 环形链表
考点
- 快慢指针
- 链表的环
题解
class Solution {
public:
bool hasCycle(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 && fast == slow) return true;
}
return false;
}
};
思路
判断链表中是否存在环,需要用到快慢指针
令slow
为慢指针,每次移动一个单位;令fast
为快指针,每次移动两个单位
两个指针同时移动,若相遇且fast
不为nullptr
时,即存在环
为什么快慢指针可以解决
如果不存在环,快指针肯定将慢指针远远抛在身后
一旦存在环,快指针会比慢指针更早到达环内,并且在环内无限循环
如果慢指针也进入环内,那么就变成追击问题了,或者俗称的龟兔赛跑
数学题
如图所示,快慢指针都是顺时针移动;若两指针距离X
,环周长为C
,那么快指针需要移动C-X
个相对距离长度才能相遇
追击问题中,有以下常识:
相对速度
=
速度差
\text{相对速度}=\text{速度差}
相对速度=速度差
相遇时间 = 相对距离长度 相对速度 \text{相遇时间}=\frac{\text{相对距离长度}}{\text{相对速度}} 相遇时间=相对速度相对距离长度
所以,再经过 C − X 2 − 1 \frac{C-X}{2-1} 2−1C−X次移动后,快慢指针就可以相遇了
为什么快指针每次移动两个单位
正如刚才提到的相遇时间计算公式,我们必须保证相对距离长度可以被相对速度整除才能相遇
因为在具体的程序实现上,所谓的相遇时间
其实就是循环次数,不可能为小数;若取两个单位,相对速度就是1,任何数都可以被1整除
所以,快指针每次移动也可以取三个单位,四个单位,五个单位…但是不一定可以整除相对距离长度
如果相遇时间是小数,说明两个指针会错过而永不相遇
快指针移动单位 | 慢指针移动单位 | 相对速度 | 相对距离长度 | 相遇时间 |
---|---|---|---|---|
2 | 1 | 1 | 4/5 | 4/5 |
3 | 1 | 2 | 4/5 | 2/2.5 |
4 | 1 | 3 | 11/15 | 3.67/5 |
更多
恭喜你完成本题!
你可以选择继续下一题,或移步至仓库开始更多类型的挑战:https://fi3wey.github.io/
仓库内包含了更多经典案例的逻辑剖析与实现细节,助你在算法的学习之旅上一往无前!
看官若还满意,还请Star一下哟~
关注公众号峰狂算法
,获取最新的刷题指导呀~