【题目】给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
【思路】首先判断是否有环存在,定义两个指针,快指针每次移动两步,慢指针每次移动一步,如果能相遇即指向同一位置,则说明有环的存在,反之不存在。判断出有环之后需要找到环的入口,方法是相遇时,慢指针继续前进,快指针从头部开始前进,并且一次移动一步,再相遇时的节点就是环的入口节点。
设头部到入口节点的距离为a,入口到相遇点的距离为b,相遇点到入口的节点为c。则环的长度是b+c,相遇时,快指针的路程为a+n(b+c)+b(n表示绕环的圈数),慢指针的路程为a+b,又因为快指针一次走两步,速度是慢指针的两倍,所以快指针的路程也等于2*(a+b)
即:a+n(b+c)+b = 2*(a+b)
化简的 a = (n-1)(b+c)+b,除去绕环的圈数,说明相遇点到入口节点的距离和头部到入口节点的距离一样,两个指针同时前进,每次前进一步,再相遇时就是入口节点。
【代码实现】
class Solution:
def EntryNodeOfLoop(self, pHead):
#首先判断边界条件
if pHead == None:
return None
fastPointer = pHead
slowPointer = pHead
#循环,如果有环,等两个指针相遇结束循环
#因为一次跳两格,所以要判断下一个
while fastPointer and fastPointer.next:
fastPointer = fastPointer.next.next
slowPointer = slowPointer.next
if fastPointer == slowPointer:
break
#fastPointer为空或者它下一个为空,说明没有环,返回None
if fastPointer == None or fastPointer.next == None:
return None
fastPointer = pHead
while fastPointer != slowPointer:
fastPointer = fastPointer.next
slowPointer = slowPointer.next
return fastPointer