鍊錶的一些問題經常會在面試中出現,這類題目能很好的反映出程式設計師的程式設計基本功,以及思維的縝密程度。寫**之前,最好能仔細分析一下題目,列出關鍵點。其實思路是最重要的,思路如果正確,**實現不是問題,更像是乙個翻譯的過程。下面是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 為問題的解,從後往...