[程式設計|20分] 鍊錶中環的入口結點
時間限制:c/c++ 1秒,其他語言 2秒
空間限制:c/c++
32768k,其他語言 65536k
題目描述
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。
思路:
已知鍊錶帶環,那麼我們便不需要判斷鍊錶帶環與否,而主要關注找到環入口的方法:
設定兩個指標(pfaster, pslower),初始值都指向頭,pslower每次前進一步,pfaster每次前進二步,
第一種方法:當fpaster若與slower相遇時,pslower肯定沒有走遍歷完鍊錶(這是因為如果這個鍊錶整整體是個環的話,當pslower恰好到達鍊錶終點的時候pfaster正好追上pslower,當這個環不是全部鍊錶部分的時候,則肯定在pslower到達終點的時候就被faster追上了),而faster已經在環內迴圈了n圈(n>=1)。假設pslower走了s步,則faster走了2s步(faster步數還等於s加上在環上多轉的n圈),設環長為r,則:
因為2s = s + nr
所以得出s= nr
設整個鍊錶長l,環入口與相遇點距離為x,起點到環入口點的距離為a。
則有a + x = s 推出 a = nr
分解有a + x = (n – 1)r +r = (n-1)r + l - a
a = (n-1)r + (l – a – x)
(l – a – x)為相遇點到環入口點的距離,由此可知,從煉表頭到環入口點等於(n-1)迴圈內環+相遇點到環入口點,於是我們從煉表頭、與相遇點分別設乙個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。
參考1參考2
程式描述如下:
/*
struct listnode
};*/
class solution
if (pfaster == null || pfaster->next == null)
return null;
pslower = phead;
while (pslower != pfaster)
return pslower;
}};
還有一種方法就是使用乙個指標,每次遍歷乙個的時候把這個節點的位址存到乙個vector,下乙個遍歷的時候從vector中查詢看是否存在,如果在指標為null之前,出現了在vector中的節點,則說明有環存在。
下面看如何從兩個相交鍊錶找出相交點,其實這是鍊錶環的乙個衍生問題
一、將其中乙個鍊錶首尾相連,檢測另外乙個鍊錶是否存在環,如果存在,則兩個鍊錶相交,而檢測出來的依賴環入口即為相交的第乙個點。
二、如果兩個鍊錶相交,那個兩個鍊錶從相交點到鍊錶結束都是相同的節點,我們可以先遍歷乙個鍊錶,直到尾部,再遍歷另外乙個鍊錶,如果也可以走到同樣的結尾點,則兩個鍊錶相交。
這時我們記下兩個鍊錶length,再遍歷一次,長鍊表節點先出發前進(lengthmax-lengthmin)步,之後兩個鍊錶同時前進,每次一步,相遇的第一點即為兩個鍊錶相交的第乙個點。
python實現
思路:
同樣的兩個指標乙個faster、乙個slower同時從乙個鍊錶的頭部出發,faster一次走2步,slower一次走一步,如果該鍊錶有環,兩個指標必然在環內相遇,此時只需要把其中的乙個指標重新指向鍊錶頭部,另乙個不變(還在環內),這次兩個指標一次走一步,相遇的地方就是入口節點。
# -*- coding:utf-8 -*-
# class listnode:
# def __init__(self, x):
# self.val = x
# self.next = none
class
solution:
defentrynodeofloop
(self, phead):
pfaster = phead
pslower = phead
while pfaster is
notnone
and pfaster.next is
notnone:
pfaster = pfaster.next.next
pslower = pslower.next
if pfaster is pslower:
break
ifnot pfaster or
not pfaster.next:
return
none
pfaster = phead
while (pfaster != pslower):
pfaster = pfaster.next
pslower = pslower.next
return pfaster
演算法 鍊錶中環的入口結點
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。這個題目很經典 但是這種快慢指標的想法的原因我還沒有明白其中的由來 還有不明白為什麼快指標只能走2步,或者又是什麼道理,沒懂 但是清楚的明白一點就是,快慢指標相遇的點一定是在環內,那麼根據這個點在環內轉圈再次遇到即就能得到環的大小n,也就是環中結點的個數...
刷題 鍊錶中環的入口結點
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。思路一 使用一前一後兩個指標,兩個指標相差n步,n代表環中結點的數目,這兩個指標相遇的結點剛好是環的入口。如何得到環中結點的數目?使用一快一慢兩個指標,如果這兩個指標相遇,表明鍊錶中存在環,並且相遇的結點一定在環內,可以從這個結點出發,一邊走一邊計數。思...
鍊錶中環的入口結點
乙個鍊錶中包含環,請找出該鍊錶的環的入口結點。class listnode public class solution return p1 return null 分析 假設鍊錶的起始點到環的入口點節點數為k,環的的節點數為x,讓p2的速度是p1的兩倍,p1和p2相遇在環的第y各節點,可以得到如下等...