標籤:blog http 使用 strong 2014 問題 log sp 時間
鏈表的題目總體來說細節比較多,因為鏈表的題目在操作鏈結表的過程中本身有些複雜,所以如果鏈表作為編程題出現的時候,多數情況下題目本身的思路可能不是很複雜,不要把題目往複雜的方向去思考就好了~這裡的鏈表只是說單向鏈表,雙向鏈表,跳錶。樹的鏈表表示形式不屬於這個鏈表的範疇。
1.合并兩個有序的鏈表。額外空間要求O(1)。
思路很明確的一個題目,三個指標。
2.如何判斷一個鏈表中是否存在環?如果存在環,如何快速的找出環的起點位置。
這個題目只要見過一次就很難再忘記它的解題方法了,非常有技巧的一個方法。fast和slow兩個指標,如果存在環,兩個指標必定會相遇。而且相遇的時候,fast改為逐步前進,slow從頭指標位置開始逐步前進,相遇的地方即為環開始的位置。這個可以利用數學知識推導一下。
3.給定一個有序的迴圈鏈表和迴圈鏈表中的一個任意指標,返回迴圈鏈表的中位元(如果是奇數,則返回中位元,如果是偶數,返回上中位元和下中位元的平均值)
有序的迴圈鏈表,可以很容易的斷定鏈表開始的位置,最小值。這樣可以統計迴圈鏈表的長度,然後從開始的位置進行計數。另外一個特殊的邊界情況是所有值都相等。
4.判斷兩個單鏈表是否相交?如果兩個單鏈表相交,求出相交的第一個節點的位置。
如果兩個單鏈表能夠行至相同的尾節點,則必定相交。
求取第一個相交節點的方法需要掃描第一個鏈表長度L1,第二個鏈表長度L2,然後將長的鏈表首先前進max(L1,L2) - min(L1,L2),然後兩個鏈表的指標同時前進,第一個相遇的節點及為相交的節點。
5.如果上述的兩個單鏈表中其中一個存在環或者兩個都存在環的情況又該如何處理?
a.如果兩個鏈表都不存在環,則使用上面的方法,
b.如果一個鏈表存在環,另外一個不存在,則兩個鏈表不相遇,
c.如果兩個鏈表均存在環,並且相遇,則說明兩個鏈表在相遇後共用一個環。
其中這裡針對每個鏈表,找環的方法為題目2,找環開始的位置也為題目2。在c的情況中,判斷是否共用環的方法及找到其中一個鏈表環開始的位置,然後從該位置到該位置進行一次遍曆,如果中間存在另外一個鏈表環開始的位置,則兩個鏈表共用一個環,並且相遇,可以返回任意一個環開始的位置。
共用環的單鏈表
6.實現一個函數,重新排序鏈表,新鏈表結構為偶數節點鏈表->奇數節點鏈表->NULL。舉例:L0->L1->L2->L3->L4->L5->L6 => L0->L2->L4->L6->L1->L3->L5->NULL
操作當前節點的時候儲存next pointer至一個臨時指標,然後next = next->next,這樣偶數就連偶數,奇數就串連奇數了。第一次遇到的奇數儲存一個oddhead指標,eventail指標指向oddhead指標,oddtail指標指向NULL,返回evenhead指標。
7.O(1)時間內能夠刪除一個單鏈表中給定的節點嗎?
針對非尾部節點,有一個小技巧可以應用一下,將給定節點的下一個節點的值copy至該節點,刪除給定節點的下一個節點,看起來像是刪除了該節點一樣。
8.快速取得單鏈表倒數第K個節點。
fast,slow指標的問題,fast先走k個單位,然後fast和slow指標一起向後,fast達到尾部節點的時候,slow剛好得到倒數第k個節點。
9.單鏈表的逆序操作(屬於單鏈表的基本操作,應熟練掌握)
10.判斷單鏈表是不是迴文結構?
11.針對單鏈表進行如下操作 L0->L1->L2->...->Ln->NULL => L0->Ln->L1->Ln-1->...Ln/2->Ln/2+1->NULL
這三個題目放在一起的原因是,10,11中將鏈表的逆序視為基本操作,如果不能實現鏈表的逆序,則10,11更無從談起。11題目在leetcode中遇到過,所以思路很清晰,因為11題的思路能夠快速的解決10,所以10的思路也很清晰。兩個題目在操作之前均需要進行一個中間步驟。
完成鏈表後半部分的逆序:L0->L1->L2->L3->L4->L5->L6->L7 => L0->L1->L2->L3<-L4<-L5<-L6<-L7,這樣就有一個head指標指向L0,一個tail指標指向L7,判斷迴文需要向中間靠攏即可,
需要11那種重新排序也只需要向中間靠攏即可。
尋找單鏈表的中位元利用尋找倒數K個節點的方法,然後+上鏈表逆序完成操作。
12.利用O(1)的額外空間拷貝隨機鏈表。
隨機鏈表指節點除了包含next還包含一個random指向鏈表中任意一個節點。
如果O(n)時間複雜度,建立一個新舊節點的hash表即可,如果O(1)的時間複雜度,只能採用下面的技巧了。
鏈表的基礎題目學習(EPI)