面试题23:链表环的入口节点

# -*- 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

浙公网安备 33010602011771号