Hello,大家好,我是阿月。坚持刷题,老年痴呆追不上我,今天刷:环形链表 II
题目
考察点
- 判断链表是否环
- 如果有环,如何找到这个环的入口
代码实现
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) {
return null;
}
ListNode slow = head;
ListNode fast = head;
boolean hasCycle = false;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
hasCycle = true;
break;
}
}
if (!hasCycle) {
return null;
}
// 将慢指针重新定位到链表的头部
slow = head;
// 以相同的速度移动慢指针和快指针,直到它们再次相遇
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow; // 返回环的起点
}
实现总结
- 使用快慢指针找到相遇点。快指针每次移动两步,慢指针每次移动一步,直到它们相遇。
- 一旦相遇,将慢指针重新定位到链表的头部,同时保持快指针在相遇点。
- 接着,慢指针和快指针以相同的速度(每次一步)移动,直到它们再次相遇。相遇的节点将是环的起点。
- 时间复杂度: O(n),其中 n 是链表的长度,因为在最坏情况下,快指针需要遍历整个链表一次才能确定是否存在环。
扩展问题
如何判断有环在坚持刷题|环形链表已经学习过,那么为什么再次相遇会是入环的起点呢?