题目:
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
示例:
1.
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
2.
输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。
3.
输入:head = [1], pos = -1 输出:false 解释:链表中没有环。
思路:
快慢指针求解,因为假如有环的话,说明整体是连通的,那么此时设置一个快指针,一个慢指针,其中快指针一次走2步,慢指针一次走1步。这样的话,如果存在环,快慢指针迟早是会相遇的,即证链表中有环。
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
# 判断是否有环,快慢指针。
# 若有环,则快慢指针必然会相遇
slow = fast = head # 快慢指针,开始都在头结点处
while fast:# 当快指针不为空时,开始遍历。
fast = fast.next # 先快指针前进一步
if fast: # 如果此时快指针不为空,继续前进一步。(避免出现示例3的情况,一步一步测试)
fast = fast.next
if fast == slow: # 如果快慢指针相遇,则返回True,说明有环
return True
# fast = fast.next.next
slow = slow.next # 慢指针前进一步
return False
注:如果存在环,如何判断环的长度呢?
方法是,快慢指针相遇后继续移动,直到第二次相遇。两次相遇间的移动次数即为环的长度。