一.解题方向:
1.判断链表是否带环?
2.若是带环返回第一个环的地址,不带环则返回NULL
二.思路分析:
(1).判断是否带环:
可用快慢指针法,即先分别定义慢 、快指针:slow、fast,使slow一次走一步,fast一次走两步,如果有环,两个指针必定进环相遇。
注意(为防止空指针对其他指针访问):倘若只进行fast=fast->next 则只需判断fast是否为空
若进行fast=fast->next->next 则既需判断fast也需判 断fast->next是否为空
代码证明(有没有可能错过,永远追不上?):
问题拓展:若是slow一次走一步,fast一次走三步可能追上吗?
(1).还是如上,假设slow进环时,fast与slow的距离是N,则:(C为圆环周长)
(2).判断C-1是否一定为偶数(C是否一定为奇数?):
由于已知fast和slow的关系,因此我们可以列出当slow刚进环时,fast和slow所走的路程(fast路程表达式里必含C),进而求出一个带C的等式
则:slow=L
fast=L+C*x+(C-N) 其中:(x为fast在环中走的圈数)
由于3slow=fast
则:3L= L+C*x+(C-N)
化简得:2L=C*(x+1)-N
若C为偶数,则N也需为偶数(偶数-偶数=偶数),但上述已经证得:当N为偶数时无需进入第二次追击,因此C只可能是奇数!
(2).带环返回第一个环的地址,不带环则返回NULL:
分析:当两个指针相遇时,令环的起始点至相遇点的距离为N,其它参数所带表达的物理意义不变,如图:
则相遇时路程:
slow:L+N
fast: L+C*x+N (x>0) (若x=0,快慢指针路程相等,则不符题意)
因其2slow=fast
则:2(L+N)= L+C*x+N
化简得:L=C*x-N (由相遇点看,将x代为1、2...等数)
由表达式如图可继续化简:L=C*(x-1)+(C-N) (由相遇点看,将x代为1、2...等数)
方法:定义一个meet指针初始化为链表的头,使meet和fast/slow指针同时以每次一个节点的速度走,则两者必定相遇,且相遇点为环的第一个节点
整题完整代码: