給你乙個鍊錶陣列,每個鍊錶都已經按公升序排列。
請你將所有鍊錶合併到乙個公升序鍊錶中,返回合併後的鍊錶。
輸入:lists = [[1,4,5],[1,3,4],[2,6]]輸出:[1,1,2,3,4,4,5,6]
解釋:鍊錶陣列如下:
[1->4->5,
1->3->4,
2->6
]將它們合併到乙個有序鍊錶中得到。
1->1->2->3->4->4->5->6
輸入:lists =輸出:
lists =思路一:這個題和之前合併兩個有序鍊錶很像,只不過這次變成了多個鍊錶合併,當然我們會想到先讓第乙個鍊錶和第二個鍊錶合併,然後讓合併後的鍊錶於第三個鍊錶合併…一直重複即可。但是這樣做效率太低,不能oj。因此我們採用分治法,即不停的對半劃分,比如k個鍊錶先劃分為合併兩個 k/2 個鍊錶的任務,再不停的往下劃分,直到劃分成只有乙個或兩個鍊錶的任務,開始合併。輸出:
舉個例子來說,比如合併6個鍊錶,那麼按照分治法,首先分別合併0和3,1和4,2和5。這樣下一次只需合併3個鍊錶,再合併1和3,最後和2合併就可以了。**中的k是通過 (n+1)/2 計算的,這裡為啥要加1呢,這是為了當n為奇數的時候,k能始終從後半段開始,比如當 n=5 時,那麼此時 k=3,則0和3合併,1和4合併,最中間的2空出來。當n是偶數的時候,加1也不會有影響,比如當 n=4 時,此時 k=2,那麼0和2合併,1和3合併,完美解決問題,參見**如下
class
solution
n = k;
}return lists[0]
;}listnode*
mergetwolists
(listnode* l1, listnode* l2)
else
cur = cur-
>next;}if
(l1) cur-
>next = l1;
if(l2) cur-
>next = l2;
return dummy-
>next;}}
;
思路二:兩個有序鍊錶排序的思路都是一樣的,在對多個鍊錶的處理上我們也可以不採用對半劃分,用遞迴的思路來做:做法是將原鍊錶分成兩段,然後對每段呼叫遞迴函式,suppose 返回的 left 和 right 已經合併好了,然後再對 left 和 right 進行合併,遞迴的結束條件是最後只剩下了一串鍊錶,則返回這串鍊錶,這樣遞迴之後每次返回的鍊錶都是已經排好序的鍊錶。參見**如下:
class
solution
listnode*
digui
(vector>
& lists,
int start,
int end)
listnode*
mergetwolists
(listnode* l1,listnode* l2)
else}}
;
思路三:採用雜湊函式(很厲害,思路清晰簡單)
思路是將所有的結點值出現的最大值和最小值都記錄下來,然後記錄每個結點值出現的次數,這樣從最小值遍歷到最大值的時候,就會按順序經過所有的結點值,根據其出現的次數,建立相對應個數的結點。但是這種解法有個特別需要注意的地方,那就是合併後的鍊錶結點都是重新建立的,若在某些情況下,不能新建結點,而只能交換或者重新鏈結結點的話,那麼此解法就不能使用,但好在本題並沒有這種限制,可以完美過 oj,參見**如下:
class
solution
}for
(int i = mn; i <= mx;
++i)
}return dummy-
>next;}}
;
leetcode23合併K個鍊錶 高頻題
合併 k 個排序鍊錶,返回合併後的排序鍊錶。請分析和描述演算法的複雜度。示例 輸入 1 4 5,1 3 4,2 6 輸出 1 1 2 3 4 4 5 6 乙個較為合適的方法,即最小堆來做。先存在lists.length個數的最小堆,每次取最小的元素出來,再鏈上新的鍊錶。definition for ...
分治實現LeetCode 23題 合併K個排序鍊錶
紀念第一道沒有看題解做出來的困難題 分治思想 歸併排序實現合併k個排序鍊錶 由於是實現一連串已經排序的鍊錶,所以第一時間想到了歸併排序 又由於是實現多個鍊錶的總排序,為了減少時間複雜度又想到了分治思想,這一題中也就是二分法 做了這麼多天的題總算有點進步 class solution 結果陣列的頭結點...
演算法筆記 刷題2 3
b 例題4 2 比較交換實數值 c 例題4 3 比較交換3個實數值,並按序輸出 d 習題4 4 三個整數求最大值 e 習題4 10 1 獎金計算 編寫乙個c程式,要求在螢幕上輸出一下一行資訊。this is my first c program 求一元二次方程ax2 bx c 0的根,三個係數a,b...