# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def EntryNodeOfLoop(self, pHead): # write code here if pHead == None: return None # 首先判断是否有环,我们这里设置2个指针,一个快指针,每次走2步,一个慢指针,每次走1步 # 2个指针如果可以相遇,证明有环,否则,肯定快指针先指向None fastpointer = pHead slowpointer = pHead while fastpointer and fastpointer.next: fastpointer = fastpointer.next.next slowpointer = slowpointer.next if fastpointer == slowpointer: break if fastpointer == None or fastpointer.next == None: return None # 在有环的情况下,我们分析,假设慢指针走的步长那个是L,那么快指针肯定是2L # 假设未进入环的步长为s,进入环后,慢指针走的步长为d,未走的步长为m,则慢指针总共走了L = s+d # 快指针走了2L = s+n*(d+m) (假设他为了和慢指针相遇,已经在环里转了n圈),则2(s+d) = s+n*(d+m)+d # 2(s+d) = s+n*(d+m)+d===> s+d = n*(d+m)==> s = n*(d+m)-d ==> s = nd+nm-d ==> # s = (n-1)d+nm ==> s = (n-1)d+(n+1-1)m ==> s = (n-1)(d+m)+m # d+m刚好是环的长度,这个公式说明了,一个指针从pHead出发,一个指针从相遇的地方出发,如果两个指针能相遇, # 那么这个时候相遇的点就是链表的环的入口 fastpointer = pHead while fastpointer != slowpointer: fastpointer = fastpointer.next slowpointer = slowpointer.next return fastpointer