49.链表中环的入口结点
题目内容:
代码及思路:
1)先找到环中的任意一个节点
2)计算出环的长度
3)设置一个指针(快指针,先走环的长度)
4)设置一个慢指针跟在后面,当p1走到路口时,两人会相遇
关于循环链表的建立,后面补上
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if (pHead == nullptr)
return nullptr;
//寻找环中任意一个点
ListNode* pMeeting = MeetingNode(pHead);
if (pMeeting == nullptr)
return nullptr;
ListNode* p1 = pMeeting;
int lengthofloop = 1;
while (p1->next != pMeeting) //绕着整个环走
{
lengthofloop++;
p1 = p1->next;
}
//寻找入口点位置
p1 = pHead;
//让p1先走环长度的距离
for (int i = 0; i < lengthofloop; i++)
{
p1 = p1->next;
}
ListNode* p2 = pHead;
while (p1 != p2)
{
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
ListNode* MeetingNode(ListNode* pHead)
{
if (pHead == nullptr)
return nullptr;
ListNode* pSlow = pHead->next;
if (pSlow == nullptr)
return nullptr;
ListNode* pFast = pSlow->next;
while (pSlow != nullptr&&pFast != nullptr)
{
if (pSlow == pFast)
return pFast;
pSlow = pSlow->next;
pFast = pFast->next;
if (pFast != nullptr)
pFast = pFast->next;
}
return nullptr;
}
};
方法二:使用set直接快速的找到入口位置
class solution{
public:
ListNode* detectCycle(ListNode* head)
{
set<ListNode*> node_set;
while(head)
{
if(node_set.find(head)!=node_set.end()) //如果在node_set中已经出现过
{
return head;
}
node_set.insert(head); //将节点插入到node_set中间
head=head->next;
}
return nullptr;
}
};