前言
一個風清月皎的夜晚,小萊獨自在操場漫步。突然一個熟悉的身影從旁邊經過,小萊定睛一看,這不是心怡很久的女神嗎?小萊快走幾步追上女神後打了個招呼就徑直往前走了(沒出息)。爲了加深女神對自己的印象,小萊決定再來一次偶遇(回頭是不可能回頭的)。只見小萊加快了步伐,終於再次偶遇到了自己的女神.....
本期主要分爲以下幾個部分:
判斷是否有環
環的長度
環的入口
鏈表長度
畫外音:關於單鏈表知識,請點擊回顧。
判斷是否有環
如圖,這是一個鏈表存在環的示意圖。
我們如何來判斷是否有環呢?小萊偶遇女神的例子或許對我們有所啓發。
在A點小萊和女神第一次相遇(起點)。
爲了再次相遇,小萊在女神保持速度不變的情況下,採取了加(風)快(馳)步(電)伐(掣)的策略。由於操場是個環形,那麼在兩個人一快一慢的場景下必然會再次相遇,於是在B點小萊又遇到了自己的女神。
畫外音:操場上想盡快遇到妹子,橫穿草坪超近道也是可以的哈!
那麼結合到鏈表裏如何處理呢?接下來我們的主角就該登場了:
「 快慢指針 」
在鏈表環的問題中我們常常用快慢指針來進行處理,即設置slow、fast兩個指針變量(slow可以看作女神,fast可以看作小萊):
slow每次走一步,即slow->next;
fast每次走兩步,即fast->next->next;
如果slow和fast相遇的話,即可以判斷當前鏈表中有環。
代碼實現:
環的長度
既然知道了鏈表中有環,那麼如何計算這個環的長度呢?
小萊和女神在B點相遇了,那麼女神按照小萊的軌跡走一遍再回到B點,行走的路程不就是環的長度嗎?
畫外音:真他孃的聰明。
代碼實現:
p節點用來記錄B點的位置。
環的入口
如圖所示,現在我們想要知道環的入口位置。
假設 A到C的距離爲x,C到B的距離爲y,環的長度爲r。在B點相遇時,女神走的距離爲s,那麼小萊的距離則爲2s(速度是女神的2倍)。
那麼可以根據:
s = x + y;2s = x + y + n * r;
推導出:
x = n * r - y;
畫外音:n表示相遇時快指針(小萊)比慢指針(女神)多走的環數。
根據這個公式,我們可以設置兩個指針,一個在相遇點B,一個在起點A,然後兩個指針同時走(每次走一步),當這兩個指針相遇時,此時的位置即爲環的入口點。
鏈表長度
進行到這裏,鏈表長度的問題就簡單的多了。
根據前面兩步,我們知道了環的長度r,同時在獲取環的入口時可以計算出起始點到入口的距離x。那麼鏈表的長度L就很容易得出來了。
鏈表長度L = 起始點到入口的長度x + 環的長度y
我目前是在職前端開發,會前端,懂java,知Python,如果你現在也在學習前端,瞭解前端,渴望成爲一名合格的前端開發工程師,在入門學習前端的過程當中有遇見任何關於學習方法,學習路線,學習效率等方面的問題,你都可以申請加入我的前端學習交流羣:518672693。裏面聚集了一些正在自學前端的初學者,羣文件裏面還有我整理的一些不錯的前端學習手冊,前端面試題,開發工具和PDF文檔書籍教程,需要的話都可以自行來獲取下載。