题目描述:
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路1:按照剑指offer上的思路

/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode* meetnode=meetNode(pHead);
if(meetnode==nullptr)
return nullptr;
int nodenum=1;
ListNode* pNode=meetnode;
while(pNode!=meetnode){
nodenum++;
pNode=pNode->next;
}
pNode=pHead;
for(int i=0;i<nodenum;i++){
pNode=pNode->next;
}
ListNode* p2=pHead;
while(pNode!=p2){
pNode=pNode->next;
p2=p2->next;
}
return pNode;
}
ListNode* meetNode(ListNode* pHead){
if(pHead==nullptr)//空链表
return nullptr;
ListNode* slow=pHead->next;
if(slow==nullptr)//只有一个节点的链表
return nullptr;
ListNode* fast=slow->next;
while(fast!=nullptr&&slow!=nullptr){
if(fast==slow)
return fast;
slow=slow->next;
fast=fast->next;//不能连续跳两个,否则会导致指向不知道的地址空间
if(fast!=nullptr)//保证fast一个节点一个节点向后跳
fast=fast->next;
}
return nullptr;
}
};

思路2:采用一个map容器,存储对应的节点及是否访问过,如果没访问过,则将节点加入map中,如果再一次碰到已经加入map中的节点,则说明找到了环的入口节点

/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead==nullptr||pHead->next==nullptr)
return nullptr;
map<ListNode*,bool> visited;
ListNode* p=pHead;
while(p){
if(visited.find(p)==visited.end()){
visited.insert(make_pair(p,true));
}else{
return p;
}
p=p->next;
}
}
};