链表如果有环,称为循环链表;问题在于链表发生环的位置不确定,收尾相连自然很好;大多数情况下环发生在链表内部,如何用最少的空间判断链表的环呢?有一个有意思的思路,定义两个指针,temp和temp2,每次循环temp2走两步,temp走一步,当temp2—>next为null或者temp2—>next—>next为null时即链表无环,当temp==temp2时链表有环。为什么呢?我们选择temp作为temp2的参考系,那么当环存在时,temp2一直在以1的速度在环内追赶temp,有限长度时可以追上。这就是经典的快慢指针法。如何查找入口节点呢?假设temp走过的距离是a+b(假设a处就是入口节点处),链表环的长度是b+c,那么temp2走过的距离是a+2b+c.由于temp2的速度是temp的两倍,有等式a+2b+c=2*(a+b)===》a==c,有了距离相等的条件,此时把temp指针移到原点,那把temp2的移动速度降低到每次移动一个结构体,那么两个指针相遇的地方就是链表环的入口处了。这种算法如果没听说过很难自己想到,所以mark一下。
附上leetcode c++代码
class Solution {
public:bool hasCycle(ListNode *head) {
ListNode *temp,*temp2;
temp=head;
temp2=head;
bool flag(0);
if(temp==NULL)
return 0;
if(temp->next==NULL)
return 0;
while(1)
{ if(temp2==NULL)
{flag=0;break;}
temp=temp->next;
if(temp2->next==NULL)
{flag=0;break;}
temp2=temp2->next->next;
if(temp2==temp)
{flag=1;break;}
}
return flag;
}
};