环形链表
题目描述:
给定一个链表,返回链表开始入环的第一个节点。?如果链表无环,则返回?null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
链接:
142. 环形链表 II - 力扣(LeetCode) (leetcode-cn.com)
解题思路
思路一:利用Map、Set、WeakMap、WeakSet
var detectCycle = function (head) {
if (head === null) {
return null;
}
const visited = new Set();
while (head !== null) {
if (visited.has(head)) {
return head;
}
visited.add(head);
head = head.next;
}
return null;
};
时间复杂度: O(n)
空间复杂度: O(n)
思路二:利用快慢指针
1. 先判断有无环(设置快慢两个指针,遍历单链表,快指针一次走两步,慢指针一次走一步,如果存在环,则快慢指针一定会指向同一节点,否则当快指针指向null时,快慢指针都不可能相遇);
2. 快指针移动到head,快慢指针都一次走一步,相遇就返回快指针或慢指针;
原理如下:
var detectCycle = function (head) {
if (head === null) {
return null;
}
let slow = head, fast = head, isCycle = false;
while(fast.next !== null && fast.next.next !== null) {
fast = fast.next.next;
slow = slow.next;
if (fast === slow) {
isCycle = true;
break;
}
}
if (!isCycle) {
return null;
}
fast = head;
while (fast !== slow) {
fast = fast.next;
slow = slow.next;
}
return fast;
}
时间复杂度: O(n)
空间复杂度: O(1)
|