解法一:
如果链表中环 有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。
当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。
所以首先要得到环中结点的数目。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* meetNode(ListNode* head)
{
ListNode*slow = head,*fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return fast;
}
return NULL;
}
ListNode *detectCycle(ListNode *head) {
ListNode* mnode = meetNode(head);
if(mnode==NULL)return NULL;
int numofCycle=1;
ListNode* p = mnode;
while(p->next!=mnode)
{
p=p->next;
numofCycle++;
}
ListNode* p2=head,*p3=head;
for(int i=0;i<numofCycle;i++)
p2=p2->next;
while(p2!=p3)
{
p2=p2->next;
p3=p3->next;
}
return p2;
}
};
由于fast每次走2步,slow每次走1步,那么相遇时假设在第K个节点,那么fast走了2K步。
设圆圈大小为N,那么fast应该多走了m圈,也就是m*N个节点。那么2K-K=m*N==>K=m*N;其实m是不是1不影响最后结果,
我使得指针slow指向链表头,然后两个指针一起每次走一步,那么已知fast和slow相距m圈距离,当slow走到入口处的时候,
fast由于多走m圈,所以肯定会在入口处相遇。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* meetNode(ListNode* head)
{
ListNode*slow = head,*fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return fast;
}
return NULL;
}
ListNode *detectCycle(ListNode *head) {
ListNode* mnode=meetNode(head);
if(mnode==NULL)return NULL;
ListNode* p = head;
while(p!=mnode)
{
p=p->next;
mnode=mnode->next;
}
reutrn p;
}
};