此題沒有代碼,是一道面試題。題目很好理解,有個鏈表,先判斷是否有環,若是有環則求出環的入口。面試
這道題跟好幾位offer收割機討論過,基本都是已知leetcode或哪裏的方法,證實該方法的正確性。指針
我和我家陽哥,試圖證實,策略是能夠推導出來的。證實以下:code
首先,要判斷一個鏈表是否有環,機智的作法是快慢指針,令快指針fast每次走兩步,慢指針slow每次走一步,那麼fast若是能和slow相遇,就證實,鏈表中有環。leetcode
那麼有環以後,如何尋找環的入口呢?ast
(1)首先,咱們定義幾個變量:變量
(2)其次,咱們須要證實一個結論---slow入環後,一圈以內一定與fast相遇List
這個結論其實很好證實,咱們用反證法。假設slow走了一圈又回到了RingEntry,這一過程當中,都沒與fast相遇。當slow回到RingEntry時,fast一定在距RingEntry爲pos的位置。這一狀態與slow剛入環時的狀態同樣,在這一圈中slow與fast都沒有相遇,那麼以後只會不斷重複以前的路徑,永不會相遇。方法
由於咱們堅信 有環的話,slow和fast必相遇的,於是上述假設不成立,slow入環後,一圈以內一定與fast相遇。鏈表
(3)有了(2)的結論,就能夠得出下列等式:co
2x = x + k * r + pos(k表示fast在環中已經繞的圈數) ------> pos = x - k * r
2y - y = r - pos ------> y = r - pos
r - y = r - r + pos = pos = x - k * r ------> r - y + k * r = x
之因此要把k * r移到 等號 的左邊,是由於 k * r 表明着繞着環 k 圈,到達的位置仍是 r - y步後到達的位置。
根據最後一個等式,咱們就能夠看出,slow再向前走 x 步 必定會到RingEntry。
因此尋找環入口的方式爲:相遇點後,slow 從相遇點開始,tmp從 ListHead 開始,同時每次走一步,兩個相遇點就是RingEntry!