struct listnode
};class solution
} if (flag == 1)//說明有環
return meet;
} else}};
給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。
因為之前接觸過帶環的鍊錶所以寫這道題的時候直接想到了快慢指標,程式放到牛客網上也是直接通過了,但是在看其他大神提交的**的時候,感覺自己寫的**還是很混亂,多了很多其他不需要的東西。
之前的部落格已經講解過一次帶環鍊錶去求入口點和環的長度了,這裡我們再簡單的說一下。
簡單來說我們平時的單鏈表是只有黑色部分的,鍊錶的最後乙個結點的next指標是指向空位置,但是帶環的不一樣,最後乙個節點的next指標指向了之前的乙個節點,通俗點來說這種鍊錶是沒有尾巴的沒有最後乙個結點,所以這種鍊錶如果用while迴圈來遍歷的話會是乙個死迴圈,進去就出不來了,我們就是用這個特點來去算他是不是帶環的鍊錶,那也就是說我們需要用while迴圈來實現我們的程式,但是我們怎麼知道我們的while迴圈是不是結束了,通過程式執行時間?還是通過程式崩潰...這都不是很好的辦法,所以我們就用了快慢指標,就是有兩個指標乙個指標快乙個指標慢,假如我們現在兩個指標都從頭結點開始出發,快指標一次走兩個節點也就是
fast = fast->next->next;
慢指標一次走乙個
slow = slow->next;
如果說這個鍊錶沒有環,那就是當你的fast指標是空了,說明沒有環,但是什麼情況說明有環?因為每次兩個指標走的結點數是不一樣的,所以如果是單鏈表的話兩個指標是不可能相遇的,但是如果說這個鍊錶存在環,那最終就是兩個指標都在環裡移動,乙個一次動乙個乙個一次動兩個這樣兩個指標總是會相遇的,這裡有個問題就是快指標能不能一次移動三個、四個或者更多,我上邊的部落格有答案大家可以去看。所以說如果兩個指標相遇那就說明鍊錶有環,這個還是相對容易理解的,那我們看我們怎麼去找我們鍊錶的入口位置。
我們通過一張圖來解釋,圖裡邊黑色加紅色是我們的鍊錶,紅色是鍊錶裡邊環的部分,鍊錶中環的長度也就是紅色部分的長度是c。
這裡還是要明白乙個問題,就是x一定是小於等於c的也就是說慢指標在環裡邊最多走了一圈兩個指標就相遇了,因為兩個指標離的最遠的情況就是慢指標進來,快指標剛走了環的一半這時候慢指標走半圈的時候到當前快指標的位置,快指標走的路程是慢指標的兩倍,那快指標就走了一圈又回到現在這位置了,所以這是最遠的情況所以x不可能大於c。
明白了這個問題就好辦了那就能得到乙個式子
所以說這裡還要說乙個應該注意的點就是快慢指標一定要從同乙個位置開始走。對這個式子化簡一下
橙色部分是我們的c-x,n是我們又轉了多少圈,所以我們現在讓乙個指標從相遇位置開始走,然後讓另乙個指標從頭開始走,當從頭開始走的那個指標走到環入口點的時候也就是說走了l的長度,另乙個指標走了nc-x,也是到了入口點,也就是兩個指標相遇的地方就是我們的環的入口點。
如果說這個題再加乙個求環的長度,其實更簡單,我們讓乙個指標在meet位置等著讓另乙個指標開始走,每走一次計數器加乙個一兩個指標相遇的時候計數器就是我們環的長度。
劍指Offer 鍊錶中環的入口結點
第一步 先找到環中的乙個點 第二步 確定環中有幾個元素,比如n個 第三步 讓第乙個指標先走n步,第二個指標再從頭走,兩指標相遇即為入口結點 class solution def entrynodeofloop self,phead write code here meetingnode self.m...
劍指offer 鍊錶中環的入口結點
假設x為環前面的路程 黑色路程 a為環入口到相遇點的路程 藍色路程,假設順時針走 c為環的長度 藍色 橙色路程 當快慢指標相遇的時候 此時慢指標走的路程為sslow x m c a 快指標走的路程為sfast x n c a 2 sslow sfast 2 x m c a x n c a 從而可以推...
劍指offer 鍊錶中環的入口結點
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。思路 這個思路是看到的牛客網討論區的,很清晰,所以貼過來了。假設x為環前面的路程 黑色路程 a為環入口到相遇點的路程 藍色路程,假設順時針走 c為環的長度 藍色 橙色路程 當快慢指標相遇的時候 此時慢指標走的路程為sslow x m c a 快指標走的路...