题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
----------------------------------------------------------------------------------------
1、先确定是否包含环
定义两个指针,一个指针走一个节点,一个指针走两个节点,当两个指针相等时,就表示有环,否则没有环
2、环中有几个节点
定义一个指针等于刚才相等节点,让这个指针往下走,同时计数,当走到和刚才环指针相等时,就是环节点个数n
3、环的入口节点
定义两个指针,第一个指针先走n步,然后第二个指针再走,当两个指针相等时就是环的入口地址
/*
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 || pHead->next->next == nullptr)
{
return nullptr;
}
int count_Node = 0;
ListNode *oneptr = pHead->next;
ListNode *twoptr = pHead->next->next;
while (twoptr != NULL && oneptr != NULL)
{
if (oneptr == twoptr )
{
count_Node = EntryNodeOfLoop_n(oneptr);
return EntryNodeOfLoop_start(pHead, count_Node);
}
oneptr = oneptr->next;
twoptr = twoptr->next->next;
}
return nullptr;
}
int EntryNodeOfLoop_n(ListNode* oneptr)
{
int count_Node = 1;
if (oneptr == nullptr)
{
return 0;
}
ListNode *oneptr_1 = oneptr;
while (oneptr_1->next != oneptr)
{
oneptr_1 = oneptr_1->next;
count_Node++;
}
return count_Node;
}
ListNode* EntryNodeOfLoop_start(ListNode* pHead,int n)
{
if (pHead == nullptr || n <=0)
{
return nullptr;
}
int node_Start = 1;
ListNode *startptr = pHead;
ListNode *endptr = pHead;
for(int i =0; i<n;++i)//下回遇见这种相隔n个距离这种题,还是用这种方法,不容易错,而不是>n在->next
{
startptr = startptr->next;
}
while (startptr != endptr )
{
endptr = endptr->next;
startptr = startptr->next;
}
return startptr;
}
};