有环单链表,求环长、链长
这是一个关于单链表的经典例题。即,给定一个有环的单链表,求环长、链长等。或者,给定一个单链表,判断是否有环?
可以遍历这个链表,将每一个节点存入一个有顺序的集合,同时判断当前节点是否在这个集合中出现,从而判断该链表是否有环以及求环长与链长。当时空间复杂度与时间复杂度都过大了。
另一个经典方法就是快慢指针,即两个指针同时从链表头开始走,快指针一次走2步,慢指针一次走1步。于是
假设这个有环链表的join点之前的节点数为a,环长为n,两个指针相遇点距离表头距离为a+b。如上图,其中k表示快慢指针相遇的时候,快指针走过环的圈数。
那么,让快慢指针同时从表头出发,当它们相遇的时候,让慢指针回到表头,并让快指针的步长变为1。等到它们再次相遇的时候,相遇点即为链表环的join点。
原因如上图,快指针再走a个节点(此时每步走一个节点)就会到达join点,慢指针从表头开始走a个节点也会到达join点。
这样即可判断给定单链表是否有环。也能求解环长以及链长。
代码如下:
class Node:
def __init__(self, val):
self.val = val
self.next = None
def buildRingedLinkList