演算法題 求帶環鍊錶中環的入口結點

2021-08-20 13:34:55 字數 2437 閱讀 8721

[程式設計|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各節點,可以得到如下等...