目录
1.实质:
一种指针算法,使用两种移速不同的指针检测是否有环
2.可以解决解决的问题:
1.检测是否是环。
2.环的起点节点。
3.环的长度。
1 .检测是否是环。
定义了两个速度不同的指针,在链表上移动,如果链表中有环,快指针先一步进入环然后循环,当慢指针也进入环后,
两个指针都在环中,且他们速度不同,所以他们早晚会相遇,如果遇到了空节点直接停止循环。
模板:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
auto *fast=head,*slow=head;
while(fast != nullptr) {
slow = slow->next;
if(fast->next==nullptr) { //有判空功能,又有条件判断功能。
return false;
}
fast = fast->next->next;
if(fast==slow) {
return true;
}
}
return false;
}
};
对应练习题:leetcode:141. 环形链表
对应题解:https://blog.csdn.net/m0_63442383/article/details/124130803
2.入环的第一个节点。
1.假设 fast指针走了f步,slow指针走了s步,链表起点和入环的起点的距离是a,环的长度是b。则f和s差了整数倍的环的长度,设这个为k 。
f = 2s,f=s+k*b,故f=2kb,s=kb,
2.从起点到环入点,再绕环转k圈,走的步数n = a+kb,又因为slow已经走了kb步,故当slow指针再走a步就会到环入点。
3.设一个指针指向头节点,走a步会与slow指针走a步重合,所让这两个指针同时走,当slow指针与该指针重合时,该节点为入环的第一个节点
复杂度分析:
时间复杂度 O(N)
空间复杂度 O(1)
具体题目与题解:142. 环形链表 II(leetcode)_橘子掀开夜晚的博客-CSDN博客
//模板:
ListNode *detectCycle(ListNode *head) {
auto *fast=head,*slow=head;
while(fast != nullptr) {
slow = slow->next;
if(fast->next==nullptr) { //充当节点判空,和循环条件判断
return nullptr;
}
fast = fast->next->next;
if(fast==slow) {
auto tmp=head;
while(slow!=tmp) {
tmp=tmp->next;
slow=slow->next;
}
return tmp;
}
}
return nullptr;
}
3.环的长度。
当两个快慢指针相遇时,一个指针固定,另一个指针遍历,当他们再次相遇时,即可求出长度。