🌟 引言
链表环检测问题在 C++ 中同样是一个经典面试题。本文将用 C++ 实现 LeetCode 142 题'环形链表 II'的解决方案,深入讲解快慢指针算法的原理和实现细节。
🔍 问题描述
给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回 nullptr。
🧠 解题思路回顾
快慢指针算法
- 使用两个指针:
slow每次走一步,fast每次走两步 - 如果两指针相遇,说明链表有环
- 将其中一个指针重置到链表头,然后两指针以相同速度前进
- 再次相遇的位置就是环的起点
数学原理
设:
- 链表头到环起点距离:
a - 环起点到相遇点距离:
b - 相遇点到环起点距离:
c
则有:
- 第一次相遇时:
slow走了a+b,fast走了a+b+c+b - 因为
fast速度是slow的两倍:2(a+b) = a+2b+c - 推导得:
a = c
💻 C++代码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
// 边界条件处理
if (head == nullptr || head->next == nullptr) {
return nullptr;
}
ListNode *slow = head;
ListNode *fast = head;
// 第一阶段:检测是否有环
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
break; // 相遇说明有环
}
}
// 检查是否因为无环退出循环
(fast == || fast->next == ) {
;
}
slow = head;
(slow != fast) {
slow = slow->next;
fast = fast->next;
}
slow;
}
};


