解題筆記(13) 幾個鍊錶的問題

2021-07-08 12:12:59 字數 2888 閱讀 9046

鍊錶的一些問題經常會在面試中出現,這類題目能很好的反映出程式設計師的程式設計基本功,以及思維的縝密程度。寫**之前,最好能仔細分析一下題目,列出關鍵點。其實思路是最重要的,思路如果正確,**實現不是問題,更像是乙個翻譯的過程。下面是4道關於鍊錶的題目,網上都有思路解答。自己實現了一下,供網友參考。下面各題的鍊錶結點定義如下:

[cpp]view plain

copy

print?

struct

listnode  

};  

問題1:輸入乙個鍊錶的頭結點,反轉該鍊錶,並返回反轉後鍊錶的頭結點。

思路:可以定義兩個輔助指標,乙個指向當前結點,設為pcur;乙個指向前乙個結點,設為pprev,然後反轉 pcur->next = pprev。但是原來的pcur->next

丟失了。可以再定義乙個輔助指標pnext,用來儲存這個值。另外就是一些為空的判斷,需要加倍小心。

參考**:

[cpp]view plain

copy

print?

listnode* reverselist(listnode *phead)  

return

ppre;  

//ppre變為第乙個結點

}  

問題2:輸入乙個鍊錶的頭結點,從尾到頭反過來輸出每個結點的值。

思路:有很多解法,網上常見的有三種,一般都能想到。(1)可以利用問題1的結果,反轉鍊錶,然後再輸出。(2)用遞迴實現。(3)用棧,其實與解法2相似,遞迴的本質其實就是棧的思想。給出後兩種解法的**。

參考**:

[cpp]view plain

copy

print?

//棧實現

void

reorderprint_solution1(listnode * phead)  

while

(keystack.size() > 0) 

//出棧

}  //遞迴實現

void

reorderprint_solution2(listnode * phead)  

}  問題3:給定鍊錶的頭指標和乙個結點指標,在

o(1)

時間刪除該結點。

思路:《程式設計之美》有這道題,採用了一種「狸貓換太子」的方法,非常形象。真正刪除的是下乙個結點,同時將原刪除結點的資料項設為下乙個結點的資料項。《程式設計之美》中假定刪除結點不是第乙個結點,也不是最後乙個結點。本問題中,沒有這個限制,如果是刪除的最後結點。只能從頭遍歷,找到前驅結點。但是平均的時間複雜度為o(1)。

參考**:以下**基於刪除結點一定在鍊錶中這個假設。

[cpp]view plain

copy

print?

listnode* deletenode(listnode* phead, listnode* pdeleted)  

else

else

delete

pdeleted;  

pdeleted = null;  

}  return

phead;  

}  

問題4:兩個單向鍊錶,找出它們的第乙個公共結點。

思路:(1)可以利用雜湊來做,根據第乙個鍊錶的位址,建立一張雜湊表,然後針對第二個鍊錶的每乙個結點,查詢雜湊表,如果找到,那麼這個結點就是第乙個公共的結點。這種方法的時間複雜度為o(len(h1)+len(h2)),空間複雜度為o(len(h1))。(2)何海濤給出的,非常巧妙,時間複雜度為o(len(h1)+len(h2)),空間複雜度為o(1)。乙個重要的思想就是,如果兩個鍊錶等長,那麼讓它們同時向前移動,一定能同時到達第乙個公共結點,能想到這一點,解法自然而然就有了。所給的兩個鍊錶不一定等長,只需遍歷一下,分別求出鍊錶的長度,然後將長鍊錶先往前移動兩者的長度之差,再同時向前。下面給出這兩種方法的具體演算法。

參考**:

[cpp]view plain

copy

print?

listnode* findfirstcommonnode_solution1(listnode *phead1, listnode *phead2)  

//開始尋找

pnode = phead2;  

while

(pnode != null)  

return

pnode;  

}  

[cpp]view plain

copy

print?

//求鍊錶長度

intlengthoflist(listnode *phead)  

return

len;  

}     

//用何海濤的方法

listnode* findfirstcommonnode_solution2(listnode *phead1, listnode *phead2)  

//調整長鍊表的長度

for(

inti = 0; i < lendiff; i++)  

plong = plong->next;  

listnode *pnode = null;  

while

(pshort != null)  

pshort = pshort->next;  

plong = plong->next;  

}  return

pnode;  

}  

鍊錶中的幾個問題以及特殊鍊錶

判斷兩個單鏈表是否相交,如果相交,給出相交的第乙個點 兩個鍊錶都不存在環 比較好的方法有兩個 一 將其中乙個鍊錶首尾相連,檢測另外乙個鍊錶是否存在環,如果存在,則兩個鍊錶相交,而檢測出來的依賴環入口即為相交的第乙個點。二 如果兩個鍊錶相交,那個兩個鍊錶從相交點到鍊錶結束都是相同的節點,我們可以先遍歷...

解題筆記(15) 幾個棧和遞迴的問題

本文介紹了幾個棧和遞迴的問題,當然遞迴的本質就是棧。這些問題網上都能找到解答,自己思考並實現了一下,供參考。問題1 跳台階問題。具體描述,乙個台階總共有n級,如果一次可以跳1級,也可以跳2級。求總共有多少總跳法,並分析演算法的時間 雜度。思路 簡單分析一下,這道題不難。假設f n 為問題的解,從後往...

解題筆記(15) 幾個棧和遞迴的問題

本文介紹了幾個棧和遞迴的問題,當然遞迴的本質就是棧。這些問題網上都能找到解答,自己思考並實現了一下,供參考。問題1 跳台階問題。具體描述,乙個台階總共有n級,如果一次可以跳1級,也可以跳2級。求總共有多少總跳法,並分析演算法的時間 雜度。思路 簡單分析一下,這道題不難。假設f n 為問題的解,從後往...