链表中环的入口结点

 

 

 解题思路:

1、先判断有没有环

2、如果有环在判断入口结点,如果没有环,直接返回None

判断有环没环的方法是:

定义两个指针,一个快指针,一次走两个长度,一个慢指针,一次走一个长度,当快指针与慢指针重合时,说明有环。

找入口结点的思路:让慢指针停留在两个指针相遇的地方,快指针回到pHead,当快指针(此时快指针距离入口结点的距离和慢指针到入口结点的距离相等)和快指针相遇时,即为入口结点。

如果slow走了L的长度,那么fast就走了2L的长度
假设从开始到入口结点的长度为s,slow在环里面走的长度是d
那么L=s+d
假设环内slow没走的长度是m,
fast走的长度是(m+d)*n+d+s=2L
带入(m+d)*n+d+s=(s+d)*2
n(m+d)=s+d
s=nm+(n-1)d
s=m+(n-1)(m+d)
m+d是环的长度

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def EntryNodeOfLoop(self, pHead):
        # write code here
        #首先判断有环无环
        #两个指针一个快指针一次跳两步一个慢指针一次跳一步
        #循环跳
        #要么fast指针为空(没有环),要么是快慢相等(有环)
        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#有环
        if fastPointer ==None or fastPointer.next==None:
            return None#无环
        #如果slow走了L的长度,那么fast就走了2L的长度
        #假设从开始到入口结点的长度为s,slow在环里面走的长度是d 
        #那么L=s+d
        #假设环内slow没走的长度是m,
        #fast走的长度是(m+d)*n+d+s=2L
        #带入(m+d)*n+d+s=(s+d)*2
        #n(m+d)=s+d
        #s=nm+(n-1)d
        #s=m+(n-1)(m+d)
        #m+d是环的长度
        
        #入口结点
        fastPointer=pHead
        while fastPointer!=slowPointer:
            fastPointer=fastPointer.next
            slowPointer=slowPointer.next
        return fastPointer
        

 

posted @ 2021-04-08 08:49  努力中的小菜鸟  阅读(53)  评论(0)    收藏  举报