问题展示
如标题所示
代码思考
那么对于这样一个问题,采用如下的思路:采用一个快指针和一个慢指针,当快指针和慢指针相遇时,即认为单链表有环;比较好理解方法就是将这个环比做成一个操场,一个人跑得快,一个人跑得慢,当跑得快的人追上了跑得慢的人,就认为这是一个环
代码展示
#include <iostream>
class Node{
public:
Node* next;
};
//核心代码
bool isExitloop(Node* head)
{
Node* slow = head;
Node* fast = head;
while( fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast) break;
}
return !(fast ==NULL || fast->next ==NULL);
}
引申判断环的入口点
如果有环,那么可能需要判断环的入口点
根据两人相遇的结论,过了时间t后
t + nR = 2t
=>t = nR
=>a + b = (n-1)R + R
=>a = (n-1)R + R -b
考虑第一次相遇的情况
=> a = R-b
那么得出一个结论,相遇点得到后,相遇点到环的距离R-b等于起始点到环的入口点的距离a,此时,快指针速度和慢指针速度一致,瑕疵相遇时即为环的入口点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* slowListnode = head;
ListNode* fastListnode = head;
while(fastListnode->next != NULL && fastListnode != NULL)
{
slowListnode = slowListnode->next;
fastListnode = fastListnode->next->next;
if(slowListnode == fastListnode) //第一次相遇
{
slowListnode = head;
while(slowListnode != fastListnode ) //找到环的入口点
{
slowListnode = slowListnode->next;
fastListnode = fastListnode->next;
}
return slowListnode;
}
}
if(fastListnode == NULL && fastListnode->next == NULL ) //
{
return NULL;
}
}
};