解法1
使用哈希表(额外存储区)存储已经遍历过的节点
var hasCycle = function(head) {
// 空链表
if(!head) return false
// 使用集合存储,也可以使用set
let set = new Set()
while(head){
// 只要访问过程中有已经访问过就是环了
if(set.has(head)){
return true
}else {
set.add(head)
head = head.next
}
}
return false
};
解法2
双指针发(快慢指针法),使用快慢指针,快指针一次向前2个节点,慢指针一次向前1个节点。
- 有环的链表中,快指针和慢指针最终一定会在环中相遇。
- 无环的链表中,快指针会率先访问到链表尾,从而终结检测过程。
var hasCycle = function(head) {
// 空链表
if(!head) return false
// 前驱节点pre 当前节点cur
let pre = head,cur = head;
// 慢的走一步,快的走两步
while(cur && cur.next){
pre = pre.next;
cur = cur.next.next
if(pre === cur){
return true
}
}
// cur = null
return false
};