直接回答
经典做法是快慢指针(Floyd 判环):慢指针每次走一步,快指针每次走两步,若链表有环,快指针迟早追上慢指针,二者相遇即有环;若快指针走到 null 则无环。时间 O(n)、空间 O(1)。
展开解析
为什么一定相遇:快指针进入环后,相对慢指针每步接近一个身位,环内距离逐步缩短,最多一圈内相遇。备选方案是哈希集合存访问过的节点地址,发现重复即有环,空间 O(n),实现直观但不是面试官想听的。追问方向:如何找环的入口——相遇后让一个指针回头部、另一个留在相遇点,同速前进,再次相遇处即入口,可由路程关系(2(a+b)=a+b+n·L 推导)证明;如何求环长——相遇后绕一圈计数。易错点:快指针判断要写 fast && fast.next 两步都非空,否则空指针异常。
示例
def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow is fast:
return True
return False