給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null
如何確定是否有環
第二種方式
定義:兩個 指標,乙個是慢指標,乙個是快指標
假設 slow 走了 l 步,那麼 fast 就走了 2l 步。
我們 鍊錶的頭部 到 鍊錶的環的入口結點處 的距離是 s
那麼 從入口結點 到 我們 快慢指標相遇的地點 的距離 為 d。
鍊錶的環中,慢指標走過的距離是d,那麼沒走過的距離是m。
我們不確定的是快指標在鍊錶的環裡走過了多少圈來與慢指標相遇,因此 將這個引數設定為n。
那麼 l = s + d
2l =
2(s+d)
= n*
(m + d)
+ d + s
由上面公式 推導出 n(m+d)
= s + d
得到:s = n(m+d)
-d;s = nm +
(n-1
)(d)
s = m +
(n-1
)(m+d)
# -*- coding:utf-8 -*-
# class listnode:
# def __init__(self, x):
# self.val = x
# self.next = none
class
solution
:def
entrynodeofloop
(self, phead)
:# write code here
#首先需要定義兩個指標,其中乙個快,跳兩步,乙個慢跳一步。
#迴圈跳
#要麼是快的指標 為 none(沒有環),要麼是快慢指標相等(有環)。
if phead ==
none
:return
none
#定義兩個指標,乙個快的乙個慢的。
fastpointer = phead
slowpointer = phead
#當快指標存在時,而且快指標的結點指向的下乙個也存在
while fastpointer and fastpointer.
next
:#那麼讓快指標走兩步
fastpointer = fastpointer.
next
.next
#讓慢指標走一步
slowpointer = slowpointer.
next
#如果慢指標等於快指標時,那麼就說明這個鍊錶中有環。有環的話那麼就跳出,break
if fastpointer == slowpointer:
break
#如果說兩個指標沒有相等的時候,快指標就已經走到鍊錶的盡頭了,說明這個鍊錶沒有環。那麼就返回none。
if fastpointer ==
none
or fastpointer.
next
==none
:return
none
#如果slow 走了 l 的長度 那麼 fast 就走了 2l 的長度
#假設 從開始到入口點的長度是 s;slow 在環裡面走的長度是 d
# 那麼 l = s + d
#假設 環內 slow 沒走的 長度 是 m; fast 走的長度是多少
# fast 走的長度 就是 ( m + d ) * n + d + s = 2 l
#帶入 ( m + d ) * n + d + s = 2 (s + d )
# s = m + (n-1)(m+d)
#有環的話,那麼就讓快指標從頭開始走,這次一次走一步,
fastpointer = phead
#此時慢指標還在環裡走著,沒有走到結點
while fastpointer != slowpointer:
fastpointer = fastpointer.
next
slowpointer = slowpointer.
next
#當兩個指標相等時,就會相遇,這時返回乙個指標的值,就為 入口結點處。
return fastpointer
鍊錶中環的入口結點
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。class listnode public class solution return p1 return null 分析 假設鍊錶的起始點到環的入口點節點數為k,環的的節點數為x,讓p2的速度是p1的兩倍,p1和p2相遇在環的第y各節點,可以得到如下等...
鍊錶中環的入口結點
題目要求 乙個鍊錶中包含環,請找出該鍊錶的環的入口結點 分析 1 一種比較偷懶的方法就是遍歷鍊錶,並直接利用hashmap來儲存已經遍歷過的結點。一旦發現已經儲存過的結點,那麼該結點就是環的入口結點。2 參考自 我簡單畫了乙個圖 上傳之後一直是橫過來的。不知道為什麼轉不正 設定兩個指標p1和p2,乙...
鍊錶中環的入口結點
題目描述 乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。思路1 設環中結點數是n,環的入口位置是x 距離起點走多少步 用快慢指標p,q,q移動的速度是p的2倍,當兩個指標相遇時p走的步數是y,q走的步數是2y,q比p多走k個環的距離,即 2y y kn,則y kn。p距離環的入口點的距離為y x,此...