解题分析:其实此题可以分解为三个题目:1)如何判断一个链表中是否包含环?2)如何找到环的入口节点?3)如何得到环中节点的数目?
解决此题:可以设置两个指针,一快一慢。
1.两个指针一个fast、一个slow同时从一个链表的头部出发
fast一次走2步,slow一次走一步,如果该链表有环,两个指针必然在环内相遇,(如果相遇就证明此链表包含环,否则没有环,解决问题1)
2.1 此时只需要把其中的一个指针重新指向链表头部,另一个不变(还在环内),
这次两个指针一次走一步,相遇的地方就是入口节点(解决问题2,得到环的入口节点)。
2. 2 接着步骤1,如果两个指针相遇,必然在环内,所以可以从这个节点出发,一遍继续向前移动,一遍计数,当再次回到这个节点时,就可以得到环中节点数了(解决问题3,得到环中节点数目)
#定义链表
class LNode:
def __init__(self):
self.data = None
self.next = None
class Solution:
# 创建带环的链表
def Create_LNode(self):
head = LNode()
tmp = head
i = 1
while i<=6:
temp = LNode()
if i==3:
InNode = temp
temp.data = i
tmp.next = temp
tmp = temp
i += 1
tmp.next = InNode
return head
# 输出链表
def Output_LNode(self, head):
temp1 = head.next
while temp1!=None:
print(temp1.data)
temp1 = temp1.next
# 判断链表是否有环
def Is_Round(self, head):
if head is None or head.next is None:
return None
p1 = head.next
p2 = head.next.next
while True:
if p1!=p2:
p1 = p1.next
p2 = p2.next.next
else:
return p1
return False
# 获得环的长度
def Round_Length(self, p1):
count = 1
p3 = p1.next
while p3!=p1:
p3 = p3.next
count += 1
return count
# 获得入口结点
def Enter_Node(self, head, length):
p1 = head
p2 = head
while length>0:
p2 = p2.next
length -= 1
while p1!=p2:
p1 = p1.next
p2 = p2.next
print(p1.data)
return p1
if __name__=="__main__":
solution = Solution()
# 创建链表
head = solution.Create_LNode()
# 获得相遇的指针
p1 = solution.Is_Round(head)
# 获取环的长度
lenght = solution.Round_Length(p1)
# 获得链表的入口结点
solution.Enter_Node(head, lenght)