链表判断是否存在环
快慢指针的方法
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode* plow = head;
ListNode* pfast = head;
while(pfast)
{
plow = plow ->next;
pfast = pfast->next;
if(pfast)
{
pfast = pfast ->next;
}
else
return false;
if(pfast == plow)
return true;
}
return false;
}
};
链表判断环的入口
快慢指针的方法:分为两个阶段,第一阶段先寻找是否有环,第二阶段通过快慢指针的回合点找到环的入口。
借用leetcode上的图来说明
首先环的长度为C,非环长度为F.
首先慢指针走到0处用了F步,快指针则走到了h处,h = F%C
接着满指针走(C-h)步,则快指针走到了$(2C- 2h + h)%C =C-h $,因此在此处相遇。
第二阶段,另外设一个指针在头部,向前走F步,相遇点的指针也向前走F步,则位置在((C-h + F)\%C = 0),此时相遇。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* head)
{
bool isCircle = false;
ListNode* fast = head;
ListNode* low = head;
while(fast)
{
low = low ->next;
fast = fast->next;
if(!fast) return NULL;
fast = fast->next;
if(fast == low)
{
isCircle = true;
break;
}
}
if(!isCircle) return NULL;
// second
ListNode* pcur = head;
while(pcur != low)
{
pcur = pcur->next;
low = low->next;
}
return pcur;
}
};