**题目:**给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
解法一:
思路:建立一个哈希表,将遍历过的节点存储起来,当再次遍历到此几点时,输出即可。时间复杂度和空间复杂度都为O(n)。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
map<ListNode*,int> m;
while(pHead!=nullptr)
{
if(m.count(pHead)==1)
return pHead;
else
m[pHead]=1;
pHead=pHead->next;
}
return nullptr;
}
};
解法二:
思路:因为快指针每次走2,慢指针每次走1,快指针走的距离是慢指针的两倍。而快指针又比慢指针多走了一圈。所以head到环的起点+环的起点到他们相遇的点的距离 与 环一圈的距离相等。现在重新开始,head运行到环起点 和 相遇点到环起点 的距离也是相等的,相当于他们同时减掉了 环的起点到他们相遇的点的距离。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode *fast=pHead,*slow=pHead;
while(fast!=nullptr&&fast->next!=nullptr)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
break;
}
if(fast==nullptr||fast->next==nullptr) return nullptr;
fast =pHead;
while(fast!=slow)
{
fast=fast->next;
slow=slow->next;
}
return fast;
}
};