給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出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...