链表题解——环形链表【LeetCode】
141. 环形链表
方法一
-
核心思想:
- 使用一个集合
seen
来记录已经访问过的节点。 - 遍历链表,如果当前节点已经存在于集合中,说明链表存在环;否则,将当前节点添加到集合中,继续遍历。
- 如果遍历结束(
head
为None
),说明链表没有环。
- 使用一个集合
-
时间复杂度:
- 最坏情况下需要遍历整个链表,时间复杂度为
O(n)
,其中n
是链表的节点数。
- 最坏情况下需要遍历整个链表,时间复杂度为
-
空间复杂度:
- 使用了一个集合
seen
来存储节点,空间复杂度为O(n)
。
- 使用了一个集合
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = Noneclass Solution(object):def hasCycle(self, head):""":type head: ListNode:rtype: bool"""seen = set()while head:if head in seen:return Trueseen.add(head)head = head.nextreturn False
方法二
-
快慢指针的核心思想:
- 快指针每次移动两步,慢指针每次移动一步。
- 如果链表存在环,快指针最终会追上慢指针(相遇)。
- 如果链表不存在环,快指针会先到达链表末尾。
-
时间复杂度:
O(n)
。 -
空间复杂度:
O(1)
。
def hasCycle(self, head):slow = fast = head # 初始化慢指针和快指针,都指向链表头节点while fast and fast.next: # 当快指针及其下一个节点不为空时slow = slow.next # 慢指针每次移动一步fast = fast.next.next # 快指针每次移动两步if slow == fast: # 如果快慢指针相遇return True # 说明链表存在环return False # 遍历结束,没有发现环