题目链接 LeetCode: leetcode-cn.com/problems/li… 题目简介 给定一个链表,返回链表开始入环的第一个节点。如果链表无环,这返回null。
如果链表中有某个节点,可以通过跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,使用整数pos
表示链表尾连接到链表中的位置(索引从0开始)。如果 pos 是 -1,这在该链表中没有环。
不允许修改链表
示例
输入: head = [3,2,0,-4], pos = 1
输出: 返回索引为 1 的链表节点
解释: 链表中有一个环,其尾部连接到第二个节点。
输入: head = [1,2], pos = 0
输出: 返回索引为 0 的链表节点
解释: 链表中有一个环,其尾部连接到第一个节点。
输入: head = [1], pos = -1
输出: 返回 null
解释: 链表中没有环。
解题思路 1、本题使用快慢指针的方式实现
2、慢指针每次向前走一步,快指针每次向前走两步,若快慢指针可以相遇这证明链表有环
3、若链表有环,并且快慢指针相遇时,则此时相遇的位置距离入环点和头节点到入环点的距离是一致的。 4、将一个指针返回头节点,和另一个指针一起每次向前走一步,相遇点则是入环的第一个节点 代码实现
/**
* 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) return null;
let p = head; // 慢指针
let q = head; // 快指针
// 先判断一下是否只有一个节点,只有一个节点没环,而且执行会报错,别问我是怎么知道的!!!
if(!q.next) return null;
// 循环条件:p和q不相等,并且快指针的next不为null
// p和q想等则证明有环,当前位置即为相遇点
do{
p = p.next;
q = q.next.next;
}while(p !== q && q && q.next);
// 跳出循环的有可能是是next为null,此时则无环
if(!q || !q.next) return null;
// 将p重新返回头节点
p = head;
// 两个指针都每次向前走一步,相遇时就是入环点
while( p!== q){
p = p.next;
q = q.next;
}
// 此时p 和 q想等,返回哪个都可以
return q;
}