🔗 LeetCode 142 - 环形链表 II
📌 题目描述
给定一个链表的头节点 head,返回链表开始入环的第一个节点。如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
示例:
| 12
 3
 
 | 输入:head = [3,2,0,-4], pos = 1输出:返回索引为 1 的链表节点
 解释:链表中有一个环,其尾部连接到第二个节点。
 
 | 
💡 解题思路
本题是经典的“快慢指针”问题。
- 判断是否有环: - 
- 使用两个指针,slow每次移动一步,fast每次移动两步。
- 如果 fast和slow相遇,说明链表中存在环。
 
- 找到入环点: - 
- 当 fast和slow相遇时,将其中一个指针移到链表头部,另一个指针保持在相遇点。
- 两个指针每次都移动一步,最终相遇的节点即为入环点。
 
✅ JavaScript 实现
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | var detectCycle = function(head) {let slow = head;
 let fast = head;
 
 while (fast && fast.next) {
 slow = slow.next;
 fast = fast.next.next;
 if (slow === fast) {
 let ptr = head;
 while (ptr !== slow) {
 ptr = ptr.next;
 slow = slow.next;
 }
 return ptr;
 }
 }
 return null;
 };
 
 | 
🟣 Swift 实现
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | class Solution {func detectCycle(_ head: ListNode?) -> ListNode? {
 var slow = head
 var fast = head
 
 while let nextFast = fast?.next?.next, let nextSlow = slow?.next {
 slow = nextSlow
 fast = nextFast
 if slow === fast {
 var ptr = head
 while ptr !== slow {
 ptr = ptr?.next
 slow = slow?.next
 }
 return ptr
 }
 }
 return nil
 }
 }
 
 | 
🧠 思考拓展
- 如果链表中存在多个环,算法是否仍然适用?
- 如何在不修改链表结构的情况下检测环?
- 能否在 O(1) 空间复杂度下解决此问题?