如何判斷一個單鏈表有環,並且求出交匯處

單鏈表有環的情景如下,爲了方便起見,假定入口之前的鏈表長度爲L,循環長度爲K



循環鏈表示意圖


我們可以用兩個指針,p1每次移動一格,p2每次移動兩格,初始化都爲頭結點HEAD

隨着指針慢慢推進,一定會出現以下的情況


某一時刻兩指針的情況

第一步

現在,我們可以假定再經過t次移動之後,兩者會在某一處相遇,對照上圖

對於P1,t次移動後的位置爲t % K

對於P2,  t次移動後的位置爲(x + 2 * t) % K

P1和P2相遇的充要條件爲 t % K = (x + 2 * t) % K

顯然,t = K - x就可以滿足條件,至此,P1總共遍歷了 L + K - x 個結點,也就是說P1不需要遍歷所有的結點便可以和P2相遇,即有循環

當然,如果在遍歷過程中只要P2或者P2->next爲NULL,就break,說明此鏈表沒有環


第二步

現在要求循環的起始點,顯然上圖中是陰影部分的0處,

由上面一步可知,當P1移動到所示位置時用了L次,P2移動的格數爲 2*L ,並且滿足 

2*L = L + x + r * K 即 L = x + r *k (r>=0爲P2在循環裏面轉的圈數) #1

在上一步中,最後P2的位置爲 K - x, 要讓P2移動到陰影部分0的位置,只需要P2再移動L格,

因爲根據上面的等式#1 , P2移動L 格之後的位置爲

(K - x + L) % K = (K - x + x + r * K )= ((r + 1) * K) % K = 0

 剛好在交匯處

那麼,怎麼才能讓P2移動L次呢,顯然,如果我們將P1再次指向HEAD,每次移動一格,並且此時P2每次也移動一格

移動L次之後,p1也在0處,兩者便相遇了,相遇的地方就是所求的交匯處,那麼我們要做的就是

不斷地移動P1和P2直到兩者相遇,相遇的結點便就是所求結點

代碼明天奉上,晚安

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