有环单链表的一些问题

给定一个单链表:

  1. 如何判断单链表是否有环?
  2. 如何找出环的连接点在哪里?
  3. 如何知道环的长度?

 

转载请注明出处。 

 

单链表如上图所示。

1. 设置两个指针同时遍历链表,一个指针步长为1(V),另一个步长为2(2V)。当这两个指针相遇时,单链表有环。

    

    假设链表头元素为A,环的连接点为B,链表头到环连接点的长度为L,环长度为S,

    则,当V到达B时,2V到达D,B->D长为L mod S,D->B长为S - L mod S,

    问题转化成了在环内的追逐,

    在环中,2V指针要追S - L mod S这么多距离,才能碰到V,2V和V的相对速度为1,

   所以从环内开始,指针相碰所用的时间为 (S - L mod S) / 1

   这段时间内,2V前进了2(S - L mod S),V则从B到C,前进了(S - L mod S),两者碰于C点。

 

2. 两个步长为1的指针分别从链表首节点A和碰撞点C开始向前遍历,当两者相遇时,该节点即为环的连接点B。 

   B->C长为(S - L mod S),C->B长为L mod S。

 

   当L<=S时,L mod S = L,所以 A->B = C->B = L,两者相等,必定相遇于B点;

   当L>S时,假设Floor( L / S ) = i,则当从C开始遍历的指针第i+1次经过B点时相遇;

 

3. 从碰撞点C开始,2个指针又以不同的速度追逐,当再次相遇时,V经过的步长即为环长

   

     因为相对速度为1,2V要追赶环长S的距离赶上V,所以这段时间内V刚好走过S。

 

 

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值