演算法題14 刪除鍊錶結點(時間複雜度為O 1 ))

2021-05-25 09:06:15 字數 1097 閱讀 1312

題目:給定鍊錶的頭指標和乙個結點指標,在o(1)時間刪除該結點。鍊錶結點的定義如下:

struct listnode

;函式的宣告如下:

void deletenode(listnode* plisthead, listnode* ptobedeleted);

分析:這是一道廣為流傳的google面試題,能有效考察我們的程式設計基本功,還能考察我們的反應速度,更重要的是,還能考察我們對時間複雜度的理解。

在鍊錶中刪除乙個結點,最常規的做法是從鍊錶的頭結點開始,順序查詢要刪除的結點,找到之後再刪除。由於需要順序查詢,時間複雜度自然就是o(n) 了。

我們之所以需要從頭結點開始查詢要刪除的結點,是因為我們需要得到要刪除的結點的前面乙個結點。我們試著換一種思路。我們可以從給定的結點得到它的下乙個結點。這個時候我們實際刪除的是它的下乙個結點,由於我們已經得到實際刪除的結點的前面乙個結點,因此完全是可以實現的。當然,在刪除之前,我們需要需要把給定的結點的下乙個結點的資料拷貝到給定的結點中。此時,時間複雜度為o(1)。

上面的思路還有乙個問題:如果刪除的結點位於鍊錶的尾部,沒有下乙個結點,怎麼辦?我們仍然從鍊錶的頭結點開始,順序遍歷得到給定結點的前序結點,並完成刪除操作。這個時候時間複雜度是o(n)。

那題目要求我們需要在o(1)時間完成刪除操作,我們的演算法是不是不符合要求?實際上,假設鍊錶總共有n個結點,我們的演算法在n-1總情況下時間複雜度是o(1),只有當給定的結點處於鍊錶末尾的時候,時間複雜度為o(n)。那麼平均時間複雜度[(n-1)*o(1)+o(n)]/n,仍然為o(1)。

基於前面的分析,我們不難寫出下面的**。

參考**:

值得注意的是,為了讓**看起來簡潔一些,上面的**基於兩個假設:(1)給定的結點的確在鍊錶中;(2)給定的要刪除的結點不是鍊錶的頭結點。不考慮第乙個假設對**的魯棒性是有影響的。至於第二個假設,當整個列表只有乙個結點時,**會有問題。但這個假設不算很過分,因為在有些鍊錶的實現中,會建立乙個虛擬的煉表頭,並不是乙個實際的鍊錶結點。這樣要刪除的結點就不可能是鍊錶的頭結點了。當然,在面試中,我們可以把這些假設和面試官交流。這樣,面試官還是會覺得我們考慮問題很周到的。

ps:假設要刪除a節點,a.next==b。則刪除b,並將b的值賦給a,這樣就等於刪除了a節點。

刪除鍊錶結點

劍指offer18題 刪除鍊錶的節點 題目描述 給定單向鍊錶的頭指標和乙個要刪除的節點的值,定義乙個函式刪除該節點。返回刪除後的鍊錶的頭節點。解題思路 該題在劍指offer中的原題是,給定乙個單鏈表的頭指標 指定結點指標,要求以o 1 的時間複雜度刪除該結點。解決方法為將待刪除結點的後繼結點的值 賦...

刪除鍊錶結點(時間複雜度為O 1 ))

題目 給定鍊錶的頭指標和乙個結點指標,在o 1 時間刪除該結點。鍊錶結點的定義如下 struct listnode 函式的宣告如下 void deletenode listnode plisthead,listnode ptobedeleted 分析 這是一道廣為流傳的google面試題,能有效考察...

鍊錶14 刪除鍊錶中所有指定值結點問題

問題 現在有乙個單鏈表。鍊錶中每個節點儲存乙個整數,再給定乙個值val,把所有等於val的節點刪掉。給定乙個單鏈表的頭結點head,同時給定乙個值val,請返回清除後的鍊錶的頭結點,保證鍊錶中有不等於該值的其它值。請保證其他元素的相對順序。測試樣例 2思路 題目中已經保證了鍊錶中一定有不等於val的...