環的問題:操場上,如何多次偶遇女神?

前言

一個風清月皎的夜晚,小萊獨自在操場漫步。突然一個熟悉的身影從旁邊經過,小萊定睛一看,這不是心怡很久的女神嗎?小萊快走幾步追上女神後打了個招呼就徑直往前走了(沒出息)。爲了加深女神對自己的印象,小萊決定再來一次偶遇(回頭是不可能回頭的)。只見小萊加快了步伐,終於再次偶遇到了自己的女神.....

本期主要分爲以下幾個部分:

判斷是否有環

環的長度

環的入口

鏈表長度

畫外音:關於單鏈表知識,請點擊回顧

判斷是否有環

如圖,這是一個鏈表存在環的示意圖。

我們如何來判斷是否有環呢?小萊偶遇女神的例子或許對我們有所啓發。

在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文檔書籍教程,需要的話都可以自行來獲取下載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章