给定一个链表,返回链表开始入环的第一个节点。 若是链表无环,则返回 null。git
为了表示给定链表中的环,咱们使用整数 pos 来表示链表尾链接到链表中的位置(索引从 0 开始)。 若是 pos 是 -1,则在该链表中没有环。github
set数据结构每一个遍历的节点都留痕,若是碰到重复的就说明从这里就开始入环了数据结构
// JavaScript
var detectCycle = function(head) {
if(head == null || head.next == null) return null
let curr = head
let arr = []
while (curr.next) {
if (arr.includes(curr)) {
return curr
} else {
arr.push(curr)
curr = curr.next
}
}
return null
};
复制代码
设定一个快指针和慢指针,快指针比慢指针移动的快一步,若是有环,确定会相遇,相遇的时候记录一下相遇的节点,而后再新建一个指针从头开始移动,相遇的指针也一块儿移动,两个指针确定会相遇,相遇的那个节点,就是开始入环的节点。spa
// JavaScript
var detectCycle = function(head) {
if(head == null || head.next == null) return null
let fast, slow, meet
fast = slow = head
let hasCycle = false
while (fast && slow && fast.next) {
slow = slow.next
fast = fast.next.next
if (slow === fast) {
hasCycle = true
meet = slow
break
}
}
if(hasCycle) {
let curr = head
while(curr != meet) {
curr = curr.next
meet = meet.next
}
return curr
}
return null
};
复制代码
第一种相对来讲比较直观,时间复杂度是O(n)的,可是空间复杂度较高,须要借助新的变量空间来记录遍历过的节点。
第二种方法时间复杂度也是O(n),可是空间复杂度较第一种会低不少,算是比较经典的解法。 github代码地址指针