返回
JavaScript LeetCode 142:环形链表 II,循迹找到节点的秘密
前端
2024-01-31 03:33:13
## LeetCode 142 题干解析
给你一个链表,它可能包含环。请你找出链表中环的入口结点,并返回。如果链表中没有环,则返回 null。
**示例 1:**
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
**示例 2:**
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
**示例 3:**
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。
## 算法实现
### 算法思路
我们使用快慢指针法来解决这个问题。快指针一次走两步,而慢指针一次走一步。如果链表中有环,快指针最终会追上慢指针。当快指针和慢指针相遇时,我们知道链表中有环。
然后,我们将慢指针从链表的开头开始,并让快指针继续从相遇点开始前进。当慢指针和快指针再次相遇时,它们将位于环的入口处。
### 代码实现
```javascript
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
const detectCycle = (head) => {
// If there is no cycle, return null
if (!head || !head.next) {
return null;
}
// Create two pointers, slow and fast
let slow = head;
let fast = head;
// Move the pointers until they meet
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) {
// If they meet, there is a cycle
break;
}
}
// If there is no cycle, return null
if (!fast || !fast.next) {
return null;
}
// Reset the slow pointer to the beginning of the list
slow = head;
// Move the slow and fast pointers until they meet again
while (slow !== fast) {
slow = slow.next;
fast = fast.next;
}
// The point where they meet is the start of the cycle
return slow;
};
总结
通过快慢指针法,我们可以有效地找到链表中环的入口结点。这种算法的时间复杂度为 O(n),其中 n 是链表的长度。