給定乙個單鏈表,只給出頭指標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 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是...