题目
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。
说明:不允许修改给定的链表。
进阶:
-
示例1:
示例2:
示例3:
提示
链表中节点的数目范围在范围
[0, 10]
内-10 <= Node.val <= 10
pos
的值为-1
或者链表中的一个有效索引题解
如何判断链表是否有环
动态图中的方法就是快慢指针,快指针一次动两格,慢指针一次动一各,一快一慢这就是快慢指针如何判断是否环
使用快慢指针,快的指针总比慢指针快,当快指针走到null值时,说明并没有环,但是如果是环的话,他们必定会在环内相交。一旦相交就说明环啦找出开始环的节点
如何找出开始环的节点,在快慢指针第一次相交后,将快指针恢复到初始位置,让你每次前进一格,与慢指针的速度一致,
你看从头节点到环形入口节点的路途与相遇节点到环形入口节点的路途是一样的
相遇节点到环形入口节点 = 头节点到环形入口节点
那我可以将快指针恢复到初始位置也就是头结点,让它与慢指针的的速度一致,再次相交的点就是开始环的入口节点代码
方法一 快慢指针
```javascript /**- Definition for singly-linked list.
- function ListNode(val) {
- this.val = val;
- this.next = null;
- } */
/**
- @param {ListNode} head
- @return {ListNode}
/
var detectCycle = function(head) {
let slow = head,fast = head;
/**如果有相等说明有环 /
do{
} while(slow != fast) // 跳出循环说明有环 // 让fast回到开始位置,一格一格的走 // 再次与slow相遇的地方就是环的的节点 fast = head; while(fast != slow) {/**
*判断是否无环
* 当fast的值为null 或者fast.next的值为null 说明没有下一个值啦
*/
if(!fast || !fast.next) return null;
fast = fast.next.next;
slow = slow.next;
} return fast;fast = fast.next;
slow = slow.next;
};
改进版本
```javascript
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
if(head == null || head.next == null) return null;
let slow = head, fast = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
fast = head;
while(fast != slow) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
}
return null;
};
方法二 哈希表
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
const set = new Set()
let slow = head;
while(slow != null && slow.next != null) {
if(set.has(slow)) {
return slow;
} else {
set.add(slow);
slow = slow.next;
}
}
return null;
};