当链表有环时,获取脸变环的位置的方法: 1.先按有无环的判断流程,当快慢指针不相遇,则直接返回空 2.当快慢指针相遇时,快指针回到起点,慢指针呆在原地,快慢指针以相同的速度前进,下一次相遇的地点即为环的入口位置

推导过程:

x:链表中无环的长度 y:相遇点离环初始位置的距离 z:环剩下的距离

当快慢指针相遇时:

快指针运行了: x + n(y + z) + y

慢指针运行了: x + m(y + z) + y

m,n为整数

由于快指针是慢指针的两倍,有:

x + n(y + z) + y = 2 ( x + m(y + z) + y)

进一步求得:

x + y = (n -2m)(y + z)

其中,y + z 即为环的长度

此时快指针回到起点,慢指针呆在原地,假设快指针相遇时离初始位置S,当快慢指针以相同速度继续遍历,当再次相遇时,存在以下关系:

S + a(y + z) = b(y + z) - y

a,b亦为整数,当b=n、a=2m时,即为上式的结果,此时S = x, 即快慢指针再次相遇时正好处在环初始节点位置。

class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        if pHead == None:
            return None

        fast = pHead
        slow = pHead
        is_ring = False
        while fast is not None and fast.next is not None:
            fast = fast.next.next 
            slow = slow.next 
            if fast == slow:
                is_ring = True
                fast = pHead
                break
        if is_ring:
            while fast != slow:
                fast = fast.next 
                slow = slow.next
            return fast 
        else: 
            return None