帶環單鏈表求中點

2021-06-14 00:25:48 字數 1391 閱讀 4887

首先,對於乙個n節點的單鏈環,如果給定乙個開始節點n0,然後用a,b兩個指標,分別以1和2的步長遍歷,那麼在a環了多少圈(m),a距離n0有乙個怎麼樣的偏移量(offset)的情況下,a,b會重合呢?即指向同乙個節點。

>>>讓我們跳過費神的數學推導證明什麼的,先給出答案吧。在a走完一圈之後,a,b會回到n0節點,也即a,b重合,所以m=1,offset = 0。

為什麼?

>>>有些人可能想當然的認為,重合點的偏移量和圈數可能是隨機的(好吧,至少我同學一開始是這麼認為的)。不要被上面給所謂的1和2的步長分神了,其實是這樣的,對於整數n(>=1)和2n,顯然這兩個數的最小公倍數是2n,不可能是2n+x,粗略說明偏移量是0 ,而最大公約數是n本身,粗略說明圈數是1。。。換個簡單的方式說:一圈之內,a,b必不重合,如果節點數n為偶,那麼b剛達到一圈時,a恰巧在中間點(前一半的最後一點)。雖然b的增量大,奈何a領先於b。a接下來面對的是n/2個節點,而b面對的是n個節點,所以在移動n/2次後,a和b重合在出發點。

其次,基於上面的結論,對於乙個n節點的單鏈環,當a和b從環上不同的節點開始以1和2的步長遍歷時,a和b是否會有重合的時候?

>>>一開始我和我的同學想當然的認為會重合,因為考慮這是個面試題,不會那麼詭異,所以感覺會重合。但如果要證明呢? 利用上面的結論!有人可能會懷疑上面的重合的逆過程不能窮舉所有的這裡的可能性。實際上這不同太擔心。 可以這樣考慮。從出發點出發,每移動一次,因為增量上b是2,a是1,所以a和b之間的距離會隨著移動的次數逐次加1。而總體的過程,b移動2n個點,a移動n個點,所以完全可以製造出[0, n)(半開半閉區間)的初始距離。 綜上所述,會重合。

接下來,對於乙個共有l(未知)個節點的帶環單鏈表,其中屬於環部分的節點數為l0(未知),非環部分為l1(未知)那麼如何知道環的入口節點呢?

>>>首先,其實這裡的l0是可知的。基於前面兩條,當你從煉表頭指標處,用a和b兩個指標按照1和2的步長遍歷鍊錶時,在a和b首次重合時,可以激發這樣乙個操作,那就是讓a和b繼續遍歷並計數,在一下次重合的時候就可以知道環長了,也就是l0。

>>>然後,這裡給乙個鏈結在這之前我一直屬於神yy狀態,沒怎麼用公式,所以到這裡的時候卡住了,現在巧借前人智慧型,繼續說明。ps:鏈結裡面的內容,我也有點懷疑作者有沒有徹底思考,但看了人家的東西才幡然開竅卻是事實。

設:a經過的節點數為 la = l1 + offset,lb = l1 + offset + n*l0 =2(l1 + offset)。(這裡不同於鏈結中的內容。如果你接受了我前面所說的a只需要遍歷一圈就可以和b重合,那麼這裡就無需多說了)

則:l1 + offset = n * l0。

基於上式,在求得l0的基礎上,再利用鏈結裡說的,重合後,b重新從頭節點處以1的步長遍歷(這次變成1了),那麼在接下來的重合的時候,就是環的入口節點了。因為步長都變成1了,最後offset的部分都是同時遍歷的。

至此,問題結束。

1 6帶環單鏈表

定義乙個集合用來存放結點的引用,並將其初始化為空,從鍊錶的頭結點開始向後遍歷,每遍歷到乙個結點就判斷集合中是否有這個結點的引用,如果沒有,說明這個結點是第一次訪問,還沒有形成環,那麼將這個結點的引用新增到集合中去。如果在集合中找到了同樣的結點,那麼說明這個結點已經被訪問過了,於是就形成了環。這種方法...

帶環單鏈表及單鏈表的相交

帶環單鏈表的概念 當單鏈表的尾指標指向了鍊錶上任一非尾結點時,即生成了乙個帶環單鏈表。問題一 判斷是否帶環 通過快慢指標實現判斷,注意快指標必須是兩步,慢指標必須是一步,否則可能跨過 問題二 求環的入口點 通過數學思想,方法是使用一指標指向開頭,一指標指向環中的相交點,每次各走一步,如此所得相交點即...

單鏈表帶環問題

判斷單鏈表是否帶環?若帶環,求環的長度?求環的入口點?1 2 3 4 5 6 7 8 9 不帶環 鍊錶遍歷一次,到最後的節點的下乙個節點會指向null,此時鍊錶不帶環。帶環 在判斷鍊錶是否帶環之前,應該先判斷鍊錶是否為空。空鍊錶肯定不帶環。只要鍊錶帶環,對鍊錶進行遍歷就會形成死迴圈,沒有出口。這是就...