剑指offer:找到包含环的链表的入口结点
题目: 如果一个链表包含环,如何找出环的入口结点。
分析:1.确定一个链表中包含环
使用两个指针,一个指针每次走一步,另一个走两步,如果走的
快的指针追上了走的慢的,那么链表就包含环,如果走的快的指针
走到了末尾还没有追上,那么就不含环。
2.确定入口
使用两个指针,一个指针首先走环包含的结点个数,后面指针再走
当两个指针指向同一个结点时,就找到了入口。
3.确定环中结点的个数
第一步中,如果两个指针相遇,说明有环,且当前结点在环中,
那么从这个结点进行计数,当再回到这个结点时,就可以得到环中结点的
数目。
# include<cstdio>
# include<iostream>
# define FALSE 0
# define TRUE 1
using namespace std;
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if (pHead == nullptr) return nullptr;
ListNode* pFast = pHead;
ListNode* pSlow = pHead;
ListNode* pCount = nullptr;
ListNode* pStable = nullptr;
bool Isloop = FALSE;
int count = 0;
while(pFast != nullptr && pFast->next != nullptr)
{
pFast = pFast->next->next;
pSlow = pSlow->next;
if(pFast == pSlow)
{
Isloop = TRUE;
pCount = pFast;
break;
}
}
if (Isloop != TRUE) return nullptr;
pStable = pCount;
while(pCount->next != pStable)
{
pCount = pCount->next;
count++;
}
count++; //得到环中结点的个数
// 找出口
ListNode* pAhead = pHead;
ListNode* pBehind = pHead;
for (int i = 1; i <= count; i++)
{
pAhead = pAhead->next;
}
while(pAhead != pBehind)
{
pAhead = pAhead->next;
pBehind = pBehind->next;
}
return pAhead;
}
};