劍指offer 鍊錶中環的入口結點

2021-10-02 14:11:21 字數 1509 閱讀 6927

給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。

給定乙個單鏈表,判斷其中是否有環,是乙個比較經典的問題。簡單歸納一下,單鏈表中環的問題包括:

判斷其中是否有環的存在;

如果存在環,找出環的入口點;

如果存在環,求出環上節點的個數;

如果存在環,求出鍊錶的長度;

如果存在環,求出環中距離任意乙個節點最遠的點(對面節點);

(擴充套件)如何判斷兩個無環鏈表是否相交;

(擴充套件)如果相交,求出第乙個相交的節點。

上述問題在部落格《判斷鍊錶中是否有環 ----- 有關單鏈表中環的問題》 說得很詳細,也提供了相應問題的解法,大家可以檢視。

這道題涉及的是上述問題的問題 2 。下面簡單介紹一下解決思路以及實現**。

思路首先是判斷是否存在環。如果有,則找入口點;如果無,則返回null。

判斷是否存在環:設定快慢指標,從煉表頭出發,快指標每次走兩步,fast = fast->next->next,慢指標每次走一步,slow = slow->next。這樣快指標一定會比慢指標更快進入到環內。在慢指標進入環後,且還沒繞環一圈,快慢指標必然會在環內相遇。因為慢指標在環內每次走一步,而快指標每次走兩步,每一次操作後,快指標與慢指標在環內的距離就縮短 1 步。慢指標走完環的一圈需要 r 步 (環的長度),而在慢指標進入環的那一刻,快指標與慢指標的距離小於等於 r,所以快指標必然會追上慢指標。

注:如果慢指標進入環的那一刻,也就是慢指標在環的入口處時,快指標也剛好在環的入口處,那麼快指標與慢指標相遇時,慢指標正好走完一圈。

判斷環的入口:

相遇時,快指標走過的路程 = a+(b+c)*k+b,(b+c)表示環的長度,k表示快指標已經走過 k 圈,k≥1。

相遇時,慢指標走過的路程 = a+b。

又因為快指標的速度一直是慢指標的兩倍,也就是在相遇時,快指標走過的路程也是慢指標的兩倍,則有 2(a+b) = a+(b+c)*k+b。

化簡可得:a = (b+c)*(k-1)+c

化簡後的式子表示,煉表頭到環入口的距離到環入口的距離 + (k-1) 圈環長度。所以假如有兩個指標 p1 和 p2,分別從煉表頭和相遇點出發,最後一定會相遇在環入口。

實現**:

/*

struct listnode

};*/

class solution

}if(slow==null || fast->next==null)

else

return p2;}}

};

可知,上面演算法的時間複雜度為 o(n

)o(n)

o(n)

,空間複雜度為 o(1

)o(1)

o(1)

。2.

劍指offer 鍊錶中環的入口

問題描述 給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。假設x為環前面的路程 紅色路程 a為環入口到相遇點的路程 綠色路程,假設順時針走 c為環的長度 藍色路程 設定快慢指標fast和slow,快指標的速度是慢指標的兩倍 當快慢指標相遇的時候 此時慢指標走的路程為sslo...

劍指Offer 鍊錶中環的入口節點

1.如果鍊錶中有環,可以通過快慢指標,最後快慢指標肯定會相會於環中的某個節點 2.從這個相會的節點開始,當再次遇到該節點,即可統計環中有節點數 n 3.設定兩個指標p,p1,p從頭先走 n 步,p1在頭部,然後兩個指標同時 走,當兩指標相遇時,相遇的節點即是環的入口。c struct listnod...

劍指Offer 鍊錶中環的入口結點

第一步 先找到環中的乙個點 第二步 確定環中有幾個元素,比如n個 第三步 讓第乙個指標先走n步,第二個指標再從頭走,兩指標相遇即為入口結點 class solution def entrynodeofloop self,phead write code here meetingnode self.m...