鍊錶操作 有環鏈表問題

2022-05-10 04:13:54 字數 1426 閱讀 7861

參考:

問題:判斷乙個鍊錶中是否有環。

分析:我們都知道,當乙個鍊錶中沒有環時,我們使用乙個指標能從頭遍歷到尾;當鍊表中有環時,鍊錶會在環中旋轉。

當我們只使用乙個鍊錶指標時,可想到方法就是使用額外的資料結構來儲存遍歷過的每個節點,在遍歷next節點時,判斷next節點是否已存在於儲存的節點中。

儲存結構可以選擇為hashtable,這樣的話,總體的時間複雜度為o(n),空間複雜度為o(n)。

當我們使用兩個指標時【鍊錶操作的常用技巧!】,可以設定快、慢兩個指標。

如果鍊錶中不存在環,快指標肯定最終變為null;存在環的話,快指標和慢指標都會進入到環中,因為慢指標相對快指標靜止,快指標相對對慢指標步伐為1,最終快指標一定能趕上慢指標。

此方法時間複雜度為o(n),空間複雜度為o(1)

更新:好友zhuoyuan 提出使用插樁法。

解答:1)使用hashtable,在此不表。

2)使用快、慢指標。

bool ishascycle(node* head) const

return

false

;}

問題:尋找乙個有環鏈表的第乙個入環節點。

分析:1)使用hashtable儲存已遍歷節點的方法中,獲取入環節點的時間複雜度為o(n),空間複雜度為o(n)。

2)當我們使用快慢指標時,兩個節點會相遇。

假設直線階段長度為l,兩個指標的相遇點距環的起始點距離為t,這個環的長度為s。

我們讓慢指標從head處開始運動,每次向前走一步;快指標從head->next處開始運動,每次向前走兩步。

當兩個指標相遇時,快指標旋轉了m圈,慢指標旋轉了n圈。

(l + m×s + t - 1) / 2 = (l + n×s + t) 【時間相同】

=> (m - 2×n)×s = t + l + 1

=> (m - 2×n - 1)×s + s - t = l + 1

顯然,相遇後,讓乙個指標從鍊錶起始處開始運動,另乙個指標從相遇點的下乙個節點開始運動。這樣,兩個指標會在鍊錶的起始節點相遇。

node* first_node_in_cycle(node* head) const

fast = fast->next;

slow =head;

while(fast !=slow)

return

fast;

}

問題:求有環鏈表的環的長度。

解答:在前兩問的基礎之上。

1)在使用hashtable時,求解過程顯而易見。

2)使用快、慢指標時,我們可以在指標相遇後,固定乙個指標,然另乙個指標運動。當兩個指標再次相遇時,就是一圈的距離。

時間複雜度o(n),空間複雜度o(1)。

鍊錶有環問題

判斷乙個鍊錶是否有環 解析 如果鍊錶有環,則設定乙個指標,該指標會一直迴圈下去。我們可以設定兩個指標,乙個一次走一步,乙個一次走兩步,如果有環最終兩者會相遇,否則每次走兩步的指標最先走到鍊錶尾部。如下圖 延伸 判斷兩個鍊錶是否相交 給出兩個單向鍊錶的頭指標,比如l1,l2,判斷這倆個鍊錶是否相交。1...

鍊錶有環和相交問題

問題1 這是一道演算法題,判斷乙個鍊錶是否有環,相應輸出true或者false。那怎麼考慮這個問題呢?首先想到的是遍歷鍊錶,有環與無環的區別在於,無環時遍歷會最終停止,而有環則會進入死迴圈,重複遍歷環內節點。因此可以借助於判斷節點是否第二次訪問來判斷有無環。具體做法有以下幾種 1 雜湊解法。使用乙個...

鍊錶是否相交,鍊錶是否有環問題

1 乙個單鏈表,判斷是否有環,環的入口節點 分析 兩個指標,慢指標一次走一步,快指標一次走兩步,如果有環肯定會相交 listnode pnode bool i istloop listnode head return false 找出環的入口 環入口到相遇點為x,從開始到環入口點長度為a,環長為r,...