第五天
题目
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
示例:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
思考
给出一个链表,要求判断是否存在循环的链表,题目给出的 pos 是帮助理解题意,并非是传入条件。
- 使用 map 存储递归的每个节点,并判断
- 递归内容:判断 map 中是否存在此节点
- 返回条件: 参数 link 为 null,或者 map 中存在此节点的下个节点
- 返回内容: 返回 link.next 继续执行
function hasCycle(link, map = new Map()) {
if (!link) return false;
if (map.has(link.next)) {
return true;
} else {
map.set(link.next);
}
return hasCycle(link.next, map);
}
- 快慢指针,标准解法
快慢指针,设立慢指针指向 head,快指针指向 head.next。
开始循环时,快指针每次都要多走一步,快指针永远会比慢指针先走,若是遇到环形指针,则两者都会进入循环,由于快指针每次都多走一步,所以他俩终将相遇。
若是没有循环,则快指针会先触底。
追及问题
function hasCycle(link) {
let slow = link;
let fast = link.next;
while (!fast && !fast.next) {
if (slow === fast) {
return true;
}
slow = slow.next;
fast = fast.next.next;
}
return false;
}
我哭了 空间复杂度 O(1)
牛逼
- 神奇解法 JSON.stringify
function hasCycle(link) {
try {
JSON.stringify(link);
} catch (e) {
return true;
}
return false;
}
后面继续跟一题 获取链表中间节点的题 深化快慢指针的思路