判断链表是否有环和求环的开始节点可以用快慢指针
快指针每次走两步,慢指针每次走一步
从相遇节点和头结点开始,每次走一步相遇的节点就是要求的环的开始节点:因为2(a+b)=a+b+c+d,故a=c。特别注意a=c=0的情况,即相遇节点就是头结点
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *fast=head,*slow=head,*meet=NULL;
//求是否有环和相遇节点
while(fast){
fast=fast->next;
if(fast) fast=fast->next;
slow=slow->next;//fast都没指到空指针慢指针更不会
if(fast==slow) {meet=fast;break;}//这里别忘了写break,与仅判断是否有环的写法稍微不同。
}
if(!fast) return NULL;
//求环开始节点
while(true){
if(head==meet) return head;
/*!!!还真有a=0=c的情况,即初始meet=head的情况!就是当只有两个节点的环链时!!故要把判断语句写在前面。否则会出错,就是会将第二个节点错认为环开始节点*/
head=head->next;
meet=meet->next;
}
};//函数体末尾别忘记写分号
};