力扣题目链接
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
示例1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
提示:
[0, 104]
105 <= Node.val <= 105
pos
为 1
或者链表中的一个 「有效索引」 。进阶:
你能用 O(1)
(即,常量)内存解决此问题吗?
思路:
判断链表有环的问题,可以采用快慢指针的方法来解决。我们规定快指针每次移动两步,慢指针每次移动一步,如果链表有环,那么两个指针终将相遇,此时返回true
。如果链表没环,当快指针走到链表末尾时,直接返回false
。
因为只需要维护两个指针变量,因此空间复杂度是O(1)
。
下面是完整代码:
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
if (!head || !head.next) return false;
let fast = head.next.next;
let slow = head.next;
while(fast !== slow) {
if (!fast || !fast.next) return false;
fast = fast.next.next;
slow = slow.next;
}
return true;
};
本题还可以采用JSON
的一个特性求解,就是如果对象中存在循环引用,那么执行JSON.stringify()
会报错。我们可以通过是否可以捕获到错误来判断是否有环。代码如下:
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
let flag = false;
try {
JSON.stringify(head);
} catch {
flag = true;
}
return flag;
};
当然在平常的面试或者工作中,不要使用此方法来求解。
本题考查快慢指针的应用,难度系数简单。需要注意的是,要处理边界情况,防止获取undefined
的next
属性,从而导致报错。