尋找鍊錶中環的入口節點,如果有環返回入口節點,如果無環返回none。
這道題分兩步走:
判斷鍊錶是否有環:兩個指標,一快一慢,如果相遇了就說明有環,如果走到頭了,就說明沒環。很像小學的追及問題哈。
尋找環的入口節點:這裡有一種比較容易想到的方法就是我們再定義乙個新的指標,從相遇的節點出發等到它回來,就可以知道環的長度m,然後再用兩個指標從頭節點出發,乙個先走m步,然後兩個指標再一起走,相遇的地方就是入口節點。
不過除了這種方法還有一種更簡單的方法:定義兩個節點,乙個從第一步相遇的節點出發,另乙個從頭出發,它倆相遇的位置就是環的入口節點。推導見下圖:
判斷乙個鍊錶是否有環,如果有,返回環的入口節點;如果沒有,返回none
'''defgetmeetnode
(self, phead):if
not phead:
return
none
pquick = pslow = phead
while pquick and pquick.
next
: pquick = pquick.
next
.next
pslow = pslow.
next
if pquick == pslow:
return pquick
return
none
defentryofloop
(self, phead)
:'''
兩步走:
1. 兩個指標一塊一滿,判斷是否有環,相遇則有環,到頭則無環
2. 兩個指標,乙個從相遇的節點出發,另乙個從頭出發,它們相遇時的節點就是環的入口節點
'''pmeet = self.getmeetnode(phead)
ifnot pmeet:
return
none
pnew = phead
while pnew != pmeet:
pnew = pnew.
next
pmeet = pmeet.
next
return pnew
if __name__ ==
'__main__'
: solution = solution(
) data =[1
,2,3
,4,5
,6]#**********=== case1 有環鏈表 **********====#
phead1 = listnode(0)
pcur = phead1
for num in data:
pcur.
next
= listnode(num)
pcur = pcur.
next
if num ==3:
pmeet = pcur
pcur.
next
= pmeet
#**********=== case2 無環鏈表 **********====#
phead2 = listnode(0)
pcur = phead2
for num in data:
pcur.
next
= listnode(num)
pcur = pcur.
next
pentry1 = solution.entryofloop(phead1)
pentry2 = solution.entryofloop(phead2)
assert
(pentry1.val ==3)
assert
(pentry2 is
none
("congratulations!"
)
劍指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...