一. 题目
-
题目
-
示例
二. 方法一: 集合
-
解题思路
- 用集合存储每一个节点的地址值
- 如果地址值已经在集合中存在, 则该节点是环的第一个节点, 返回该节点
- 如果遍历到列表末尾, 则说明没有环
-
解题代码
def detectCycle(self, head: ListNode) -> ListNode: res = set() while head: if id(head) in res: return head else: res.add(id(head)) head = head.next return None
-
分析
时间复杂度: O(n)
空间复杂度: O(n)
三. 方法二: 快慢指针
-
解题思路
- 和上一篇博客思路一样, 可通过快慢指针确定链表是否有环
- 然后现在的关键问题是如何找到相遇的第一个节点
- 图解分析
- 所以我们再从相遇节点和链表头同步移动, 相遇时即为环的第一个节点
-
解题代码
def detectCycle(self, head: ListNode) -> ListNode: if not head or not head.next: return None slow = head fast = head while True: if not fast or not fast.next: return None slow = slow.next fast = fast.next.next if slow == fast: break slow = head while slow != fast: slow = slow.next fast = fast.next return slow
-
分析
时间复杂度: O(n)
空间复杂度: O(1)