剑指offer-链表中环的入口节点

时间:2023-03-09 16:07:21
剑指offer-链表中环的入口节点

题目描述

一个链表中包含环,请找出该链表的环的入口结点。

解题思路

解决这个问题的第一步是如何确定一个链表中包含环。可以定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个一次走两步。如果走得快的指针走到了链表的末尾都没有追上第一个指针,那么链表就不包含环。反之则可得到环中的一个节点。

第二步是如何找到环的入口。还是可以用两个指针P1和P2指向链表的头结点,如果链表中的环有n个节点,则指针P1先在链表上向前移动n步,然后两个指针依次同时向前移动一步。当P2指向环的入口节点时,P1已经围绕着环走了一圈,又回到了入口节点。

剩下的问题是如何得到环中节点的数目。可以从第一步得到的环中节点开始每次走一步,计数走的步数直到它又回到原来的位置,就可以得到环中节点数了。

代码

 /*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
int len = LenOfLoop(pHead);
if(len == )
return NULL;
else{
ListNode* first = pHead;
ListNode* second = pHead;
while(len-- > )
first = first->next;
while(first != second){
first = first->next;
second = second->next;
}
return first;
}
}
int LenOfLoop(ListNode* pHead){ //得到环的长度
ListNode* first = pHead->next;
if(first != NULL)
first = first->next;
ListNode* second = pHead;
while(first != NULL){ //first每次走两步,second走一步,找到两者相等的节点即为环中节点
if(first == second){
break;
}
else{
first = first->next;
if(first != NULL)
first = first->next;
second = second->next;
}
}
if(first != NULL){
ListNode* loop = first;
int len = ;
while(loop != first->next){
first = first->next;
len++;
}
return len;
}
else
return ;
}
};