142. 环形链表II
分析
-
判断链表是否有环
- 设置两个指针
slow
和fast
,初始都指向链表头节点head
- 快指针每次移动两步,慢指针每次移动一步
- 如果快指针追上慢指针,说明链表中有环;否则,如果快指针或其下一节点为空,则链表无环
- 设置两个指针
-
找到环的起始节点
- 当快慢指针相遇时,将慢指针重置为链表头节点
head
- 快指针保持在相遇位置
- 两个指针每次都向前移动一步,当两者再次相遇时,相遇点即为环的起始节点
- 当快慢指针相遇时,将慢指针重置为链表头节点
数学推导
假设:
- 链表头到环入口节点的距离为
a
- 环入口到相遇点的距离为
b
- 相遇点到环入口的距离为
c
快指针比慢指针速度快一倍,因此:2(a + b) = a + b + n(b + c)
( n
为快指针在环中绕的圈数),化简得:a = c + (n - 1)(b + c)
这表明:
- 从链表头节点到环入口的距离
a
等于从相遇点沿环走回入口的距离c
- 因此,当两个指针一个从链表头开始,一个从相遇点开始,每次移动一步,最终会在环的起始节点相遇
时间复杂度
快慢指针遍历链表一次即可确定是否有环,以及找到环的起始节点,时间复杂度 O(n)
空间复杂度
空间复杂度为 O(1)
C++代码
|
|