給定一個鏈表,返回鏈表開始入環的第一個節點。 若是鏈表無環,則返回 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代碼地址指針