給一個鏈表,若其中包含環,請找出該鏈表的環的入口結點,否則,輸出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; // 返回環入口
}
};