1 题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
2 题解
2.1 哈希法
创建一个set容器,遍历链表查看set内是否存在该结点,不存在则存入set,存在说明链表有环返回结点,遍历结束则返回null,链表无环。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
set<ListNode*>s;
if(pHead==NULL)
return nullptr;
while(pHead){
if(s.count(pHead)==0)
s.insert(pHead);
else
return pHead;
pHead=pHead->next;
}
return nullptr;
}
};
2.2 双指针
题解:参考此文
初始快慢指针指向头结点,快指针一次走两步,慢指针一次走一步。若有环二者在环中一定会相遇,相遇后使快指针指向head,二者同时向前走一步,再次相遇的结点就是入口节点。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* head)
{
ListNode *fast,*slow;
fast=head;
slow=head;
while(fast&&fast->next){
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
break;
}
if(fast==NULL||fast->next==NULL)
return NULL;
fast=head;
while(fast!=slow){
fast=fast->next;
slow=slow->next;
}
return fast;
}
};
3 判断链表有无环(相似题)
也可用哈希set容器判断是否有环。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==NULL||head->next==NULL)
return false;
ListNode *fast,*slow;
fast=head;
slow=head;
while(fast&&fast->next){ //当快指针和他的next不为空时,慢指针一定不为空,可继续判断
fast=fast->next->next;
slow=slow->next;
if(fast==slow)//当两指针相遇说明有环,返回true
{
return true;
}
}
return false;// 否则返回false
}
};