题目描述
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
进阶: 你能用 O(1)(即,常量)内存解决此问题吗?
示例
示例1:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
解题思路
思路一: 借助哈希表
- 哈希表存储遍历过的节点,每遍历一个节点,都会在哈希表中找是否存在该节点;如果已经存在,就该链表说明存在环;
- 如果哈希表中不存在该节点,那么就将该节点保存,继续遍历;
- 如果链表为空,返回false
思路二: 快慢指针
- 定义两个指针slow 和 fast,从同一个节点出发,slow每次往前走一步,fast每次往前走两步,也就是说 fast 的速度是 slow 的两倍;
- 如果有环的话,那么slow 和 fast一定会相遇;
- 如果没有环的话,那么 两个指针就不会相等;
AC代码
题解一: 哈希表
var hasCycle = function(head) {
let current = head
let map = new Map()
while(current) { // 如果头节点存在,就遍历
if( map.has(current) ) // 判断map中是否存在该节点
return true // 存在就返回true
map.set(current, true) // 不存在就将该节点保存为键,值为true
current = current.next // 继续向下遍历
}
return false // 节点不存在,返回false
};
题解二: 快慢指针
var hasCycle = function(head) {
if(head == null) return false
let slow = head
let fast = head
while(fast != null) {
if(fast.next == null) { // 节点不存在,说明没有环
return false
}
slow = slow.next // 慢指针往后走一步
fast = fast.next.next // 快指针往后走两步
if(fast == slow) { // 快指针跟慢指针相遇
return true
}
}
return false
};
刷题打卡记录
这是之前的刷题记录,有兴趣的可以看下,如果有什么写的不好的地方还希望大家能够指出;或者到评论区交流学习。
Leetcode15 史上最详细题解之三数之和 | 刷题打卡
Leetcode215 数组中第K个最大的元素 | 刷题打卡
总结
写题解的过程相当于一次反省的过程,加深自己的印象。能够将题解以一种自己所理解的方式写出来的话,那就足够了,并不一定要写的多厉害,人都是会成长的。
加油,hxdm!奥力给!!!
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情