没看题解前没想到用数学式推导结点关系(当以2倍速差的指针遍历环时,相遇点到环头的距离等于头结点到环头距离)。
我用的一般思维:若有环,则找出环内结点数,重置快慢指针指向头结点,然后使它们之间结点数为环结点数+1,再以相同速度前进,当它们再次相遇时,相遇点就为环头结点。虽然时间复杂度还是O(n),但这样处理会增加一个遍历环找环结点数的时间开销。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
if(!pHead || !pHead->next || !pHead->next->next){//结点数不多于3个且不含环或头结点为空
return NULL;
}
ListNode *p=pHead,*q=pHead;//p为快指针,q为慢指针
int n=1,flag=0;//记录环内结点数,是否有环
while(p->next->next){
p=p->next->next;
q=q->next;
if(p==q){//有环
flag=1;
p=p->next;
while(p!=q){
p=p->next;
n++;
}
break;
}
}
if(!flag){
return NULL;
}
p=q=pHead;//重置指针,使包含p、q之间结点的长度为环长+1时,p、q重合点即为入环结点
int m=0;
while(m<n){
m++;
p=p->next;
}
while(p!=q){
p=p->next;
q=q->next;
}
return p;
}
};

京公网安备 11010502036488号