用快慢指標的方法。時間複雜度o(n),空間複雜度o(1)。
設定p1為慢指標,p2為快指標,兩者初始時都指向鍊錶的頭結點 ,慢指標p1每次前進1步,快指標p2每次前進2步。如果鍊錶存在環,則快指標p2肯定先進入環,慢指標p1後進入環,兩個指標必定會相遇。如果不存在環,則快指標會先行到達鍊錶的尾部變為none。
class
lnode
:def
__init__
(self, val)
: self.val = val
self.
next
=none
# 判斷鍊錶是否有環,並返回入環節點
# 判斷是否有環,用快指標和慢指標,當兩個指標相遇時,說明有環
defexit_loop
(llist)
: p1 = p2 = llist
# 當鍊表為空或者只有乙個節點時,跳出迴圈,返回false
while p2 and p2.
next
: p1 = p1.
next
p2 = p2.
next
.next
if p1 == p2:
return
true
return
false
# 如果鍊錶有環,返回入環節點
# 當確定有環後,慢指標重新回到頭節點,快指標停留在相遇處,然後兩個指標每次移動1個節點,最終他們在入環節點處相遇
deffind_entry_of_loop
(phead):if
not phead:
return
none
slow = phead
fast = phead
while slow.
next
and fast.
next
.next
: slow = slow.
next
fast = fast.
next
.next
# 當兩個指標相遇時,說明有環,迴圈結束
if fast == slow:
break
# 快指標停留在相遇處,慢指標回到起點
ifnot fast or
not fast.
next
:return
none
slow = phead
# 兩個指標每次向前移動1,當再次相遇時,相遇點即為入環節點
while slow != fast:
slow = slow.
next
fast = fast.
next
return slow
if __name__ ==
"__main__"
: llist = lnode(0)
p1 = lnode(1)
p2 = lnode(2)
p3 = lnode(3)
p4 = lnode(4)
p5 = lnode(5)
llist.
next
= p1
p1.next
= p2
p2.next
= p3
p3.next
= p4
p4.next
= p5
p5.next
= p2
print
(exit_loop(llist)
)print
(find_entry_of_loop(llist)
.val)
鍊錶判斷是否有環,如有,找入環節點
一條鍊錶如何判斷是否有環?若是有環那怎麼找到鍊錶環的入口?思路 用快慢兩個指標分別從煉表頭開始,慢指標一次走乙個節點,快指標一次走兩個節點next next,這樣如果有環那快指標務必會跑到慢指標後面,隨即兩者之間的距離一次會縮小一步,最終相遇。若是未相遇且快指標的 next 為 null,則說明鍊錶...
如何判斷鍊錶有環以及求入環節點
如何判斷單鏈表有環,並找出環的入口?時間o n 空間o 1 這個面試題還是蠻有趣的,當時只想出了第一問,第二問實在巧妙。如圖這個單鏈表,藍色的部分是環。對於如何判斷鍊錶有環,可以從起點發出兩個指標,乙個一次一步,另乙個一次兩步,如果兩個指標相遇,那麼這個單鏈表就有環。設綠色的地方是指標相遇點。對於第...
鍊錶是否有環找出入環節點位置
利用快慢指標方法判斷鍊錶是否存在環,並記錄兩指標相遇位置。快慢指標方法 將兩指標分別放在煉表頭 x 和相遇位置 z 並改為相同速度推進,則兩指標在環開始位置相遇 y 如圖所示。證明過程 x,y,z分別為鍊錶起始位置,環開始位置和兩指標相遇位置,由快指標速度的慢指標速度的2倍。快指標與慢指標均從x出發...