141. 环形链表

141. 环形链表

题目链接:141. 环形链表

题目描述

给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中存在环,则返回 true 。 否则,返回 false

核心思考:快慢指针 (龟兔赛跑)

判断链表中是否存在循环,最经典、空间复杂度最优的解法就是使用快慢指针 (Floyd 判圈算法)
试想在一个环形跑道上,跑步速度快的人最终一定会从后面追上并套圈跑步较慢的人。

  1. 设定指针:定义两个指针 p1(慢指针)和 p2(快指针),初始都指向头节点。
  2. 移动规则:慢指针 p1 每次走一步,快指针 p2 每次走两步。
  3. 判别条件
    • 如果遇到结尾(即 p2p2.next 为空),说明前方死胡同,不可能有环,直接返回 False
    • 如果两个指针在某处相遇(p1 == p2),说明快指针套圈追上了慢指针,证明有环存在,返回 True

解题思路 (Python)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
p1 = p2 = head
while p2 is not None and p2.next is not None:
p1 = p1.next
p2 = p2.next.next
if p1 == p2:
return True
return False

复杂度分析

  • 时间复杂度:O(N),其中 N 是链表中的节点数。当链表不存在环时,快指针将先于慢指针到达尾部;当链表存在环时,两者在环内相聚前,快指针走出的距离最多也就是线性规模。
  • 空间复杂度:O(1),我们只使用了慢指针和快指针这两个额外的指针载体,与链表规模无关。