题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路1:
1、判断有无环:定义两指针,quicknode每次走两步,slownode每次走一步。如果两个指针相遇,则说明有环;否则无环。
2、判断环的入口节点:相遇的节点必在环内!让slownode走一圈,计算环中节点个数count。
3、slownode和quicknode都指向头节点,先让quicknode走count步,然后两指针一起走,相遇节点即为环的入口节点。
/*
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;
//1、判断有无环
ListNode* slowNode = pHead;
// if(slowNode==nullptr)
// return nullptr;
ListNode* quickNode = pHead;
while (quickNode->next!=nullptr){ // || quickNode->next->next!=nullptr
slowNode=slowNode->next;
quickNode=quickNode->next->next;
if(quickNode==slowNode)
break;
}
//2、计算环中节点个数
int count=0;
ListNode* tmpNode = slowNode->next;
while (tmpNode!=slowNode){
tmpNode = tmpNode->next;
count++;
}
count+=1;
//3、求环的入口节点
quickNode=pHead;
slowNode=pHead;
for(int i=0;i<count;i++){
quickNode=quickNode->next;
}
while (quickNode!=slowNode){
quickNode=quickNode->next;
slowNode=slowNode->next;
}
return slowNode;
}
};
思路2:修改了思路1中2、3步;
1、先判断是否有环;
2、若有环,让quickNode指向头结点,slowNode依旧指向相遇处;让两个指针同时同频走,相遇即为环的入口节点。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if(pHead== nullptr || pHead->next==nullptr)
return nullptr;
ListNode* slowNode = pHead;
ListNode* quickNode = pHead;
while (quickNode->next!=nullptr){
slowNode=slowNode->next;
quickNode=quickNode->next->next;
if(quickNode==slowNode)
break;
}
quickNode=pHead;
while (quickNode!=slowNode){
quickNode=quickNode->next;
slowNode=slowNode->next;
}
return slowNode;
}
};