给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出None。
思路:
1.找相遇点:设置一个快指针pFast一个慢指针pSlow,先找到一个相遇点,一定在环中
2.计算环的长度: 从相遇点出发,到相遇点结束-1,即为环的长度。
3.pFast:从pHead+环的长度出发;pSlow从pHead出发,当pFast=pSlow时,即为入口节点。
class ListNode:
def __init__(self,x):
self.val = x
self.next = None
class Solution:
def MeetingNode(self,pHead):
"""
:param pHead:头节点 0
:return:
"""
if pHead == None:
return None
pSlow = pHead.next #慢指针1,每次走一步
if pSlow ==None:
return None
pFast = pSlow.next# 快指针2,每次走两步
while pFast:
if pSlow == pFast: # 当两个相等的时候返回慢指针的节点 即相遇点
return pSlow
pSlow = pSlow.next
pFast = pFast.next
if pFast:
pFast = pFast.next
def EntryNodeOfLoop(self,pHead):
meetingNode = self.MeetingNode(pHead) #传入相遇的点,以这个点为起点
if not meetingNode:
return None
NodeLoop = 1 # 计步器从1开始 ,当next指针指向相遇点时结束。
flagNode = meetingNode
while flagNode.next != meetingNode:
NodeLoop +=1
flagNode = flagNode.next
pFast = pHead # 快指针从加上步长的位置开始
for i in range(NodeLoop):
pFast = pFast.next
pSlow = pHead # 慢指针从头开始
while pFast != pSlow: # 当两个相遇时,即入口节点
pFast = pFast.next
pSlow = pSlow.next
return pFast
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)
node5 = ListNode(5)
node6 = ListNode(6)
node7 = ListNode(7)
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node5.next = node6
node6.next = node7
node7.next = node3
s = Solution()
print(s.EntryNodeOfLoop(node1).val)