题目
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
题解一
var hasCycle = function (head) {
//设置快慢指针
let slow = head;
let fast = head;
//如果没有环,则快指针会抵达终点,否则继续移动双指针
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
//快慢指针相遇,说明含有环
if (slow == fast) {
return true;
}
}
return false;
};
笔记:
- 无环怎么判断?
- 思路:准备两个指针fast和slow,循环链表,slow指针初始也指向head,每次循环向前走一步,fast指针初始指向head,每次循环向前两步,如果没有环,则快指针会抵达终点,如果有环,那么快指针会追上慢指针
复杂度:时间复杂度O(n),空间复杂度O(1)
题解二 鸡贼法
题目说了范围不超过100000,没超过size能发现空节点就是没有环, 超过了就是有环!!!
const hasCycle = function(head) {
let i = 0, size = 100000
let node = head
while (++i <= size) {
if(!node) return false
node = node.next
}
return true;
};
题解三 标记法
给遍历过的节点打记号,如果遍历过程中遇到有记号的说明已环
const hasCycle = function(head) {
while (head) {
if (head.tag) {
return true;
}
head.tag = true;
head = head.next;
}
return false;
};
题解四 JSON.stringify(head) 秒杀法😃
除非不报错,报错就是有环!!
var hasCycle = function (head) {
try {
JSON.stringify(head)
} catch{
return true
}
return false
};