給定乙個鍊錶,返回鍊錶開始入環的第乙個節點。如果鍊錶無環,則返回 null。
為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置(索引從 0 開始)。如果 pos 是 -1,則在該鍊錶中沒有環。注意,pos 僅僅是用於標識環的情況,並不會作為引數傳遞到函式中。
說明:不允許修改給定的鍊錶。
示例 1:
輸入:head = [3,2,0,-4], pos = 1示例 2:輸出:返回索引為 1 的鍊錶節點
解釋:鍊錶中有乙個環,其尾部連線到第二個節點。
輸入:head = [1,2], pos = 0示例 3:輸出:返回索引為 0 的鍊錶節點
解釋:鍊錶中有乙個環,其尾部連線到第乙個節點。
輸入:head = [1], pos = -1雙指標解決在前面講過449,快慢指標解決環形鍊錶,判斷乙個鍊錶是否是環形鍊錶,而這題比第449題稍微麻煩一點,就是如果確定鍊錶有環,還要找出環的入口。如果乙個鍊錶沒有環,就不存在環的入口。這裡主要來看一下,如果乙個鍊錶有環怎麼找到他的入口。輸出:返回 null
解釋:鍊錶中沒有環。
對於鍊錶組成的環一般有兩種,一種是o型,一種是6型,其實原理都一樣,這裡主要看一下6字型的鍊錶,他會有兩種情況,一種是環很大,如下圖所示。
根據第449題的分析,通過快慢指標可以判斷乙個鍊錶是否有環。如果有環,那麼快指標走過的路徑就是圖中a+b+c+b,慢指標走過的路徑就是圖中a+b,因為在相同的時間內,快指標走過的路徑是慢指標的2倍,所以這裡有a+b+c+b=2*(a+b),整理得到a=c,也就是說圖中a的路徑長度和c的路徑長度是一樣的。
在相遇的時候再使用兩個指標,乙個從鍊錶起始點開始,乙個從相遇點開始,每次他們都走一步,直到再次相遇,那麼這個相遇點就是環的入口。
還有一種情況就是環很小,如下圖所示
這種情況下當快慢指標在環上相遇的時候,快指標有可能在環上轉了好幾圈,我們假設相遇的時候快指標已經在環上轉了n圈。
那麼相遇的時候快指標走過的路徑就是a+b+(b+c)*n,(b+c其實就是環的長度),慢指標走過的路徑是a+b。由於相同時間內快指標走過的路徑是慢指標的2倍。
所以有a+b+(b+c)*n=2*(a+b),整理得到a+b=n*(b+c),也就是說a+b等於n個環的長度。
我們還可以使用兩個指標,乙個從鍊錶的起點開始,乙個從相遇點開始,那麼就會出現一種情況就是,乙個指標在路徑a上走,乙個指標一直在環上轉圈,最終會走到第一種情況。
所以無論哪種情況我們都可以使用第一種方式解決,**如下
public listnode detectcycle
(listnode head)
return slow;}}
return null;
}
通過集合set解決上面解法可能不是太好理解,這裡再來看一種比較好理解的,就把結點乙個個全部存放到集合set中,在存放的時候如果出現了重複的結點,說明這個鍊錶是有環的,並且首次重複的這個節點就是環的入口
public listnode detectcycle
(listnode head)
return null;
}
set的add方法表示往集合中新增元素,新增的時候如果沒有重複的就會返回true,如果有重複的就會返回false。
總結
這道題最容易想到的應該是最後一種解法,比較簡單,也很容易理解。但這道題有個要求,就是不能修改鍊錶的結構,如果沒這要求的話,還可以參照449,快慢指標解決環形鍊錶的最後一種解法,就是把鍊錶節點乙個個刪除。
環形鍊錶II(快慢指標)
題目 題解 假設該表是環形鍊錶,鏈式部分長度為a aa,環形部分長度為b bb。定義快指標fas tfast fast 和慢指標slo wslow slow 先讓fas tfast fast 每次走兩步,slo wslow slow 每次走一步,直到兩者相遇 接著讓fas tfast fast 重置...
環形鍊錶II 快慢指標
參考於 注意要用距離 幾何來理解這道題 使用快慢指標 definition for singly linked list.class listnode def init self,x self.val x self.next none class solution def detectcycle s...
環形鍊錶(快慢指標法)
給定乙個鍊錶,判斷鍊錶中是否有環。如果鍊錶中有某個節點,可以通過連續跟蹤 next 指標再次到達,則鍊錶中存在環。為了表示給定鍊錶中的環,我們使用整數 pos 來表示鍊錶尾連線到鍊錶中的位置 索引從 0 開始 如果 pos 是 1,則在該鍊錶中沒有環。注意 pos 不作為引數進行傳遞,僅僅是為了標識...