單鏈錶環問題

2021-07-31 21:46:20 字數 2692 閱讀 1777

給定乙個單鏈表,只給出頭指標h:

1、如何判斷是否存在環?

2、如何知道環的長度?

3、如何找出環的連線點在**?

4、帶環鍊錶的長度是多少?

5、如果存在環,求出環上距離任意乙個節點最遠的點(對面節點);

6、(擴充套件)如何判斷兩個無環鏈表是否相交;

7、(擴充套件)如果相交,求出第乙個相交的節點;

解法:1、對於問題1,使用追趕的方法,設定兩個指標slow、fast,從頭指標開始,每次分別前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到null退出。

2、如果存在環,求環上節點的個數:

對於這個問題,我這裡有兩個思路(肯定還有其它跟好的辦法):

思路1:記錄下相遇節點存入臨時變數tempptr,然後讓slow(或者fast,都一樣)繼續向前走slow = slow -> next;一直到slow == tempptr; 此時經過的步數就是環上節點的個數;

思路2: 從碰撞點p開始slow和fast繼續按照原來的方式向前走slow = slow -> next; fast = fast -> next -> next;直到二者再次專案,此時經過的步數就是環上節點的個數 。

3、問題3:有定理:碰撞點p到連線點的距離=頭指標到連線點的距離,因此,分別從碰撞點、頭指標開始走,相遇的那個點就是連線點。

該定理的證明可參考:

4、問題3中已經求出連線點距離頭指標的長度,加上問題2中求出的環的長度,二者之和就是帶環單鏈表的長度(鍊錶長度l = 起點到入口點的距離 + 環的長度r)

5、求出環上距離任意乙個節點最遠的點(對面節點)

如下圖所示,點1和4、點2和5、點3和6分別互為」對面節點「 ,也就是換上最遠的點,我們的要求是怎麼求出換上任意乙個點的最遠點。

對於換上任意的乙個點ptr0, 我們要找到它的」對面點「,可以這樣思考:同樣使用上面的快慢指標的方法,讓slow和fast都指向ptr0,每一步都執行與上面相同的操作(slow每次跳一步,fast每次跳兩步),

當fast = ptr0或者fast = prt0->next的時候slow所指向的節點就是ptr0的」對面節點「。

為什麼是這樣呢?我們可以這樣分析:

如上圖,我們想像一下,把環從ptro處展開,展開後可以是無限長的(如上在6後重複前面的內容)如上圖。

現在問題就簡單了,由於slow移動的距離永遠是fast的一般,因此當fast遍歷玩整個環長度r個節點的時候slow正好遍歷了r/2個節點,

也就是說,此時正好指向距離ptr0最遠的點。

對於問題6(擴充套件)如何判斷兩個無環鏈表是否相交,和7(擴充套件)如果相交,求出第乙個相交的節點,其實就是做乙個問題的轉化:

假設有連個鍊錶lista和listb,如果兩個鍊錶都無環,並且有交點,那麼我們可以讓其中乙個鍊錶(不妨設是lista)的為節點連線到其頭部,這樣在listb中就一定會出現乙個環。

因此我們將問題6和7分別轉化成了問題1和2.

看看下圖就會明白了:

針對問題6還可以思路:

1、判斷兩鍊錶最後乙個節點是否相同,如果相交,則尾節點肯定是同一節點。

時間複雜度o((length(a)+ length(b))、空間複雜度 = o(1)(儲存最後結點的位址)

2、人為構環,如上圖。

將鍊錶a的尾節點指向鍊錶b,如果b鍊錶有環,則兩個鍊錶相交,此時從鍊錶b的頭指標往下遍歷,如果能夠回到b,則說明相交

時間複雜度o((length(a)+ length(b)),沒有額外的空間消耗

針對問題7(無環相交):

1、先取得兩個鍊錶a和b的長度len(a)和len(b)

2、沿著a和b鍊錶中較長的鍊錶遍歷,使用指標追趕的方法。

設定兩個指標

fast(長鍊表)、

slow(短鍊表上)。fast在較長鍊錶先出發前進(lengthmax-lengthmin)步(即是二者的長度之差)使fast和slow指標到相交點的距離相等,之後兩個鍊錶同時前進,每次一步,相遇的第一點即為兩個鍊錶相交的第乙個點。

判斷是否存在環的程式:

bool i***itsloop(slist *head)  

return !(fast == null || fast->next == null);

}

尋找環連線點(入口點)的程式:

slist* findloopport(slist *head)  

if (fast == null || fast->next == null)

return null;

slow = head;

while (slow != fast)

return slow;

}

單鏈表成環問題

思路一 新建乙個unordered set 思路二 兩個指標,乙個走得乙個走得慢,如果相遇了肯定是有環的,參考 思路一 class solution return false 思路二 include include include includeusing namespace std struct ...

單鏈表 約瑟夫環問題

分析 比如由5個節點組成乙個環,從第1個節點開始報數,每報數2個節點刪除乙個節點,單鏈表如下 1 設定乙個helper輔助節點,指向最後乙個節點 2 因為是從第k個節點開始報數,因此先讓first和helper走k 1步,這樣first節點就指向報數的第乙個節點了,k初始值為1,因此不用向前走 3 ...

判斷單鏈錶環的問題

演算法雜類 2010 01 20 17 15 42 閱讀48 字型大小 大中小 訂閱有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是...