給你乙個單向鍊錶,已知裡面有乙個鍊錶環,你如何用程式找出環的起始位置?這是我在網上看到的問題,而給出的解決方法也頗為巧妙,大意就是:弄兩個指標,快指標和慢指標,快指標速度是慢指標的兩倍。它倆一起從煉表頭出發,不難想象,經歷一段過程之後,它倆一定會在鍊錶中的某一點相遇。然後把其中乙個指標送回煉表頭節點,另乙個指標呆在第一次相遇的位置,然後它倆再按照相同的速度繼續前進,那麼它倆第二次相遇的位置,就一定是環鏈表的起始位置。
剛開始看到這種方法時,其實我內心是懷疑的。所以立馬擼了份**驗證下,**如下:
其中的linkarr就是我們的環鏈表【本質是乙個陣列偽鍊錶,但因為我的目的只是驗證,所以就不使用結構型鍊錶了,請不要在意這些小細節】,經過若干次的實驗,證明網上給出的方法確實正確無誤!嗯,有意思,我這人好奇心頗重,無法容忍我不能理解的事物,所以就想在數學邏輯上給乙個證明,但在證明之前,讓我們先把這個專業性問題轉化為更容易理解的生活型問題: 張三和李四去環繞公園散步,他們共同從公寓出發,張三的速度是李四的兩倍。經過一段時間,張三和李四在公園的某一點相遇,於是它倆打**給王二麻子,約他一起來散步。之後王二麻子從公寓出發時,張三李四一路說說笑笑繼續散步,而且正好張三李四的速度和王二麻子相等。問,你如何證明,最終這三巨頭會相聚在公園的門口位置??為了盡可能的方便讀者朋友閱讀理解,我做了乙個簡陋小圖,如下:
其中,a點代表公寓,b點代表公園門口,c點代表張三李四第一次相遇的位置,在這裡還要補充一點,就是ab距離小於2倍公園周長。
1):首先,當張三走到b點時,李四走了1/2 ab的長度。這樣,當李四也走到b點時,張三已經在公園內溜達了,但還沒有溜達完一圈;
2):然後,當張三和李四相遇在c點時,李四還沒走完一圈,而且不難想象,張三所走的圈數大於1小於2;
3):這樣,李四從c點繼續向b點走,而張三保持速度不變的話,當李四到b點時,張三走到了d點。因為張三是李四速度兩倍,所以2cb = cd,既cb = bd;
3):最後讓我們整理下思路,看看他們實際走的總距離。李四在公園環繞一圈,還有公園到公寓的距離,所以李四走了 ab + 1圈 的總距離,因為張三快兩倍,所以張三的總距離自然是 2*(ab+1圈) 的距離,然後代入簡化,我們最後得到這樣的公式:: (ab+1圈)*2 = 2圈 + ab + bd,因為bd = cb,所以最後我們證得 cb = ab!至此證畢。
以上的證明,適用於ab距離小於公園周長。但如何ab距離超長呢?其實無所謂,不管ab距離多長,道理都是相通的。我們家鄉有句俗語叫心裡有,不會說,意思就是道理我懂,但說不出來。我現在就是這種狀態:關於ab大於2倍周長的情況,其實也可以想得通,但如果要在這裡給出文理清晰的邏輯證明,我真的做不到。因為對我而言,其中牽扯到更複雜的語言組織與數學公式,鄙人文采淺薄能力有限,就不在此獻醜了。見諒!
尋找公共鍊錶起始位置
題目 存在這樣一種情況,如果兩個單詞有相同的字尾,那我們可以將字尾作為公共部分儲存,比如being和loading,其中ing就可以作為 公共部分,現在存在兩個鍊錶,含有公共部分,設計乙個高效演算法找到其公共字尾其實位置。分析 我們可以這樣想,如果我們單純的讓兩條鍊錶的指標同步移動,那麼只有兩條鍊錶...
單向鍊錶刪除節點
單向鍊錶刪除節點的乙個技巧,這個是在 程式設計之美 上面看到的,可以用來對付一些演算法題。有時候會遇到這種情況,單鏈表提供乙個指標,要求要刪除指標指向的節點。如下 考慮到釋放記憶體,還再需要乙個指標 我們具體一下,有這麼乙個單向鍊錶,這個鍊錶的節點比較簡單,資料域只有乙個整型 並且當前的指標 ite...
單向鍊錶刪除節點
include include include include 使用隨機數的標頭檔案 using namespace std class list list del ptr list head,list ptr int main srand unsigned time null 以時間為隨機數的種子...