跟本题无关,需要仔细阅读的文章,还没阅读https://leetcode-cn.com/problems/linked-list-cycle/solution/yi-wen-gao-ding-chang-jian-de-lian-biao-wen-ti-h-2/
题目描述: 给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。如果链表中存在环 ,则返回 true 。 否则,返回 false 。
示例1:
1 | 输入:head = [3,2,0,-4], pos = 1 |
示例2:
1
2
3输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例3:
1
2
3输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
题解方法一:遍历
解题思路:
- 遍历所有节点,每次遍历到一个节点时,判断该节点此前是否被访问过
- 通过哈希表存储来判断该节点是否被访问过,每次到达一个节点,如果该节点已经存在于哈希表中,则表示该链表是环形链表,否则就将该节点存于哈希表中,重复整个过程,遍历整个链表即可。
⚠️!!同样的思路 用数组的方式遍历整个链表,显示超时,数组添加过于耗时, 可以采用ES6的 Set 数据结构。
题目分析
- 仔细阅读 题目中这段话
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
: 此处如果只判断数组中是否有环,而不考虑pos的位置,则只能通过一部分测试用例。
以这种解法为例1
2
3
4
5
6
7
8
9
10
11
12
13
14var hasCycle = function(head) {
if (head=== null||head.next == null) return false
let arr = new Set()
while(head) {
if (arr.has(head.val)){
return true
} else {
arr.add(head.val)
head = head.next
}
}
return false
};
可以通过这种没有重复val的测试用例:
1
2[3,2,0,-4]
1不可以通过这种有重复val的测试用例:14、 -21是重复的
1
2[-21,10,17,8,4,26,5,35,33,-7,-16,27,-12,6,29,-12,5,9,20,14,14,2,13,-24,21,23,-21,5]
-1
这种方法还需要优化
题解方法二:
解题思路:
1、判断链表是否有环也可以使用双指针的方式
2、快慢指针同时指向head,快指针走两步,慢指针走一步,当快指针与慢指针相遇时,说明有环。
3、因为快指针比慢指针速度快,如果存在环,那么始终会追上。
1 | var hasCycle = function(head) { |
参考链接: