給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。
找環的入口這個問題,其實是建立在另外乙個問題之上的——判斷單向鍊錶是否有環
土方法很多,但是比較好的目前就那麼乙個:一開始設定兩個指標都指向表頭,其中乙個每次(一步)前進乙個節點的叫p1,另外那個每次(一步)前進兩個節點的叫p2 。p1和p2同時走,當其中有乙個遇到null,就證明鍊錶沒有環。如何某個時刻(假設走了n步之後),p1和p2指向的位址相同,那麼鍊錶就是有環的。
接著很自然的問題就是,環的入口在**?
我是先看了答案,再去推導的,但是為了各位能夠順著思路,我下面就嘗試用順推的方式來展現結果,但是這樣做有個不好的地方,可能有人在看完答案後會想:「我去,怎麼可能想到」,這個時候由於直接看推導了,連自己推導的機會都沒有,所以我建議各位先自己嘗試想一下,想不出的話,你可以選擇兩條路:
直接看答案,然後推導,答案在此【在p1和p2重合後,p1指向表頭,然後p1和p2每次同時行走一步,每步前進乙個節點,等到p1和p2重合時,重合的位置就是環的入口】,反選就可以看到;
看順推的過程,不知道答案,但是自己看了後也沒有辦法從答案推導了,因為我已經告訴你推導方法了……要走這條路的請往下拉吧……
我們設:
l1:鍊錶的無環的部分長度,包括環的入口節點x。
l2:環的長度,包括入口節點x。
a:p1和p2的交點,即在環的入口節點後面的第a個節點。
然後我們來考察一下l1,l2,a,以及n(n是走過的步數,不是走過的節點數,p1一步乙個節點,p2一步兩個節點)的關係。
可以明確的是,p1在進入環後,走了不到一圈就在交點處和p2重合,為什麼肯定沒有走完一圈?因為p1在進入環的時候,p2和p1之間的距離(沿著行走方向)至多為 l2-1,不可能超過l2-1,因為環的大小也才只有l2 。p2追趕p1,最多隻需要走l2-1步,因為每走一步,p1和p2的相對距離減小1,那麼p1最多隻走了l2-1步,就是最多隻經過了l2-1個節點,不可能走完一圈。
現在可以列公式了:
l1+a=n;#1 //n是p1走過的節點數。
l1+k*l2+a=2*n;#2 //2*n這個是p2走過的節點數,其中的k表示p2可能在環裡面走了k圈,k>=1。
合併#1和#2:
2*(l1+a)=l1+k*l2+a;
化簡:l1+a=k*l2;
所以當a點移動l1距離時肯定是在入口結點x處,和從原點移動l1距離的指標重合在入口結點x。
public
class
solution55
return slow;}}
return null;
}@suppresswarnings
("duplicates"
)public
static
void
main
(string[
] args)
}
劍指offer55 鍊錶中環的入口結點
給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。設定塊 慢指標,快指標沒次走兩步,慢指標每次走一步,如果有環,它們一定會相遇 否則快指標會先到最後。相遇後選乙個指標在頭結點,然後與慢指標同時移動,相遇位置就為環入口 走一步和兩步 while slow fast if fas...
劍指offer 55 鍊錶中環的入口結點
給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。時間限制 1秒 空間限制 32768k 熱度指數 144136 本題知識點 鍊錶 見 struct listnode class solution while slow fast 2.計算環內長度 int l 0 dowhil...
劍指offer 55 鍊錶中環的入口結點
1.題目描述 給乙個鍊錶,若其中包含環,請找出該鍊錶的環的入口結點,否則,輸出null。2.解題思路方法1 方法2 鍊錶包含環,像數字6的圖形。1 設定快慢指標,假設快指標在環內與慢指標相遇,設頭節點到入口結點的距離為x,入口結點到相遇點為y,相遇點到入口結點距離為z,則有 x y 2 x y z ...