题目:
一个链表中包含环,如何找出环的入口节点?
思路:
可以先确定环中的结点数m,然后让一个指针p1先走m步,接着指针p2开始走。则他们相遇的结点就是环的入口地址。
so,如何确定环中结点的数目?
可以用快慢指针来,p1每次走一步,p2每次走两步,且这样走一次,count加1,当p2赶上p1的时候,count就是环中结点数。
#include <iostream>
#include <vector>
using namespace std;
struct Node{
int val;
Node *next;
Node(int _val) :val(_val), next(NULL){}
};
int NumOfNodeInLoop(Node *head)
{
if (head == NULL) return 0;
Node *pFaster = head;
Node *pSlower = head;
int count = 0;
do{
pFaster = pFaster->next->next;
pSlower = pSlower->next;
++count;
} while (pFaster!=NULL&&pFaster->next != NULL&&pFaster != pSlower);
if (pFaster == NULL || pFaster->next == NULL) return 0; //没有环
return count;
}
Node *EnterNodeInLoop(Node *head)
{
int numInLoop = NumOfNodeInLoop(head);
if (numInLoop == 0) return NULL;
if (numInLoop == 1) return head;
Node *p1 = head;
Node *p2 = head;
for (int i = 0; i < numInLoop; i++) p1 = p1->next;
while (p1 != p2)
{
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
int main()
{
Node *n1 = new Node(1);
Node *n2 = new Node(2);
Node *n3 = new Node(3);
Node *n4 = new Node(4);
Node *n5 = new Node(5);
Node *n6 = new Node(6);
n1->next = n2;
n2->next = n3;
n3->next = n4;
n4->next = n5;
n5->next = n6;
n6->next = n3;
Node *re = EnterNodeInLoop(n1);
if(re) cout << re->val << endl;
return 0;
}