给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
// 首先判断是否包含环,如果包含环,则统计环中节点的个数
// 1.使用两个指针,一个走两步,一个走一步,则一定能在环中相遇
// 2.相遇后一个节点不动,另一个节点每次走一步统计环中节点的个数
// 根据统计的个数n,使用两个指针,其中一个指针先走n步,两个指针相遇处就是环的入口处
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
int num = 0;
if(pHead == NULL) return NULL;
ListNode* p1 = pHead;
ListNode* p2 = pHead;
bool has = false;
if(p1->next == NULL) return NULL; //只含有一个节点
p2 = p1->next ->next;
while(p1 != NULL && p2!=NULL && p2->next!=NULL) { //判断是否存在环
if(p1 == p2) { // 说明存在环
has = true;
break;
} else {
p1 = p1->next;
p2 = p2->next->next;
}
}
if(has) { // 统计环中节点的个数
while(1) {
p1 = p1->next;
num++;
if(p1 == p2) break;
}
} else return NULL;
p1 = pHead;
p2 = pHead;
while(num > 0){ //提前走n步
num--;
p2 = p2->next;
}
while(p2!=p1){ // 一起往前走
p1 = p1->next;
p2 = p2->next;
}
return p1; // 返回环入口
}
};