c 鍊錶之 快慢指標 查詢迴圈節點

2022-03-18 15:02:28 字數 1790 閱讀 3703

參考:

上面分析了 根據這張圖

推倒出 數學公式。 剛接觸 不能一下弄明白。下面結合上面文章的分析。仔細推倒一下 ,

一般設定 快指標 速度是 慢指標的2倍。及 快指標每次遍歷兩個指標, 慢指標每次遍歷1個指標。

假設上圖 快慢指標 在e點相遇,那 相遇點離迴圈節點d 之間距離是x.  頭結點a 離迴圈節點d 距離為k.

那麼在兩指標相遇時,各自走過得距離(這裡可以吧上圖想成是 乙個操場,起點不在操場內):

慢指標:

k + x + n*(x+y) = m;//x+y 繞環一圈的距離;n 慢指標 總共繞了幾圈在環內.

快指標:

試想下 快指標是慢指標 速度的2倍,當它們相遇時 所用的時間是一樣的。那麼快指標 走過得距離是

2*m;

也等於k+x +n*(x+y) = 2*m;//n為快指標繞過得圈數

聯立做差上面兩公式。

(n-n)*(x+y) = m; 及

(n-n)*(x+y) = k+x+n*(x+y);//這裡x+y 環長是個定值。 假設環長為m

有:(n-n)*m = k+x+n*m;

有:k+x = (n-2*n)*m ;

最終的推倒公式 出來啦。及頭節點a 到 迴圈節點d 的距離  加上  相遇點e離迴圈節點d  是 環長的整數倍。

這個公式試用於 0 型迴圈鍊錶  和 6型迴圈鍊錶。

對於前者 起k 和 x 都為0;快慢指標起點都是迴圈節點(0型 任意一點都是迴圈節點)

那麼有 (n-2*n)*m = 0;

及 n = 2*n;  相遇時 快慢指標所繞 環的圈數 前者是後者的2倍。 可以想象速度是2唄,所用時間相同。

這裡跟環有多少節點沒有關係。

上面只是找到了相遇節點。如何找到迴圈節點。對於6型迴圈鍊錶。

還是上面推倒公式:

k+x = (n-2*n)*m;//假設n-2*n = q; 單位為圈數。

有k+x=q*m;   //再假設快慢指標能再迴圈節點相遇,那麼x = 0;

k = q*m; //q 的值和k 成正比,這個公式成立條件是 快慢指標相遇 在環上的任意乙個點,

假如是e點,結合公式  從e點轉q*m個節點 正好= k 。k的終點正好是迴圈節點d,及 如果快指標從起點a 走過k  和 慢節點 從e 走過m*q 相遇節點正好是d迴圈節點,前提是快慢指標速度相同。

假設將快指標 從頭節點開始。慢指標從上次快慢指標相遇點 開始。 兩者已相同速度移動。

當快指標走的d 迴圈節點走過距離為k,慢指標 走到d 迴圈節點走過的距離為q*m;

此時 二者相遇 節點就是迴圈節點。

分析下**:

node* findbeginning(node *phead)  

if (null == fast->pnext) //

判斷是哪種情況導致跳出迴圈

return

null;

/*查詢環起點

*/fast =phead;

while (fast !=slow)

return

fast;

}

關於快慢指標演算法:

不僅限於 迴圈鍊錶問題。

比如查詢乙個  未知長度鍊錶中中心節點

可以先遍歷長度,在遍歷到長度/2處返回節點。顯然這樣 演算法不夠優化,

使用快慢指標 遍歷。快指標速度為 慢得 2倍。

快指標遍歷完,返回的慢指標 正好是 長度/2 的節點。

鍊錶迴圈節點問題

題目描述 給定乙個鍊錶,返回迴圈開始的節點。如果沒有迴圈節點,return null,並且要求在不占用額外空間的情況下解決 解題思路 1 快慢節點確定是否會相交,若迴圈,則快慢指標會相交,若不迴圈,則快指標會指向空 2 若相交,記錄慢指標位置,並讓快指標回到頭結點,兩指標再一起走,第乙個相交點,為迴...

利用快慢指標尋找鍊錶中間節點

876.鍊錶的中間結點 這道題要求我們找到鍊錶中的中間位置,首先想到第一種方法,使用兩個指標,乙個從頭遍歷到尾部確定長度,乙個從頭遍歷到相應位置。那麼有沒有一遍遍歷就能解決的?那麼我們想到快慢指標,因為快慢指標往往可以做到一遍遍歷,在慢指標處找到答案 做法 慢指標走一步,快指標走兩步。這樣快指標到末...

鍊錶的快慢指標 查詢中點

一直做題都是陣列中點,直接算n 2,但是鍊錶的中點怎麼求出來,我還真沒見過,只能說自己做題太少了。今天做leetcode上的題就遇到了,雖然說簡單,但對我來說這是個新的知識點,我得記錄一下,如下 cpp view plain copy listnode findmidnode listnode he...