标签:第一个 str 链表 val col class 一个 扫描 lse
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
经典快慢指针,首先用快慢指针s,f从head开始扫描,设两个指针在一段时间t后相遇
此时慢指针走了t步,设t=a+b,其中a是环外的,b是环内部分
此时快指针走了2t步,同时快指针一定在环上绕了k圈,设环长度为c,有等式2t=(a+kc+b)=2(a+b)
所以a+b=kc=t
我们此时需要一个重要的结论:所有走到起始点的步数都可以表示为a+kc(显然,把环外的走了,然后走k圈环内的)
然后只要让s再往前走a步就行,为了实现这个,我们再用一个慢指针,从head出发,直到和s相遇,就是环入口
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *detectCycle(ListNode *head) { if(head==NULL)return NULL; ListNode *s=head;//慢指针 ListNode *f=head;//快指针 int t=0; while(1){//碰到NULL说明没有环 ++t; //cout<<t<<" "; if(s->next!=NULL) s=s->next; else return NULL; if(f->next!=NULL) f=f->next; else return NULL; if(f->next!=NULL) f=f->next; else return NULL; if(s==f){//快慢指针相遇 auto res=head; while(res!=s){ s=s->next; res=res->next; } return res; } } return NULL; } };
标签:第一个 str 链表 val col class 一个 扫描 lse
原文地址:https://www.cnblogs.com/zsben991126/p/13149972.html