面试题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

  

猜你喜欢

转载自www.cnblogs.com/ivyharding/p/11327568.html