Time:2019/4/10
Title: Merge K Sorted Lists
Difficulty: Difficulty
Author: 小鹿javascript
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.java
合併 k 個排序鏈表,返回合併後的排序鏈表。請分析和描述算法的複雜度。
Example:git
Input: [ 1->4->5, 1->3->4, 2->6 ] Output: 1->1->2->3->4->4->5->6
若是咱們完成了簡單的基於兩個單鏈表的合併以後,對於這個題來講,考察點是分治算法,我認爲還有一個考察點就是遞歸調用,分治的同時常常用遞歸來解決。一、本道題能夠藉助歸併排序的思想,稍加改造就能夠解決。github
二、將數組中的鏈表分治,就是不斷的將數組中的鏈表中間劃分,分別合併,而後總體合併成一個大鏈表。算法
/** * @param {number[]} nums * @return {number[]} * 功能:合併 k 個鏈表 * 邊界條件: * 1)判斷數組是否爲空 * 2)判斷數組長度爲 1 時 * 3)判斷數組長度爲 2 時 * 4)判斷數組長度大於 2 時 */ var mergeKLists = function(lists) { // 當 lists 中有一個鏈表時 if(lists.length == 0){ return null; }else if(lists.length == 1){ // 判斷數組長度爲 1 時 return lists[0]; }else if(lists.length == 2){ // 判斷數組長度爲 2 時 return mergeTwoLists(lists[0],lists[1]); }else{ // 判斷數組長度大於 2 時 // 取數組的中部座標 let middle = Math.floor(lists.length/2); // 取左右兩邊數組 let leftList = lists.slice(0,middle); let rightList = lists.slice(middle); // 遞歸、分割、合併 return mergeTwoLists(mergeKLists(leftList),mergeKLists(rightList)); } }; //兩個鏈表合併 var mergeTwoLists = function(l1, l2) { let result = null; //終止條件 if(l1 == null) return l2; if(l2 == null) return l1; //判斷數值大小遞歸 if(l1.val < l2.val){ result = l1; result.next = mergeTwoLists(l1.next,l2); }else{ result = l2; result.next = mergeTwoLists(l2.next,l1); } //返回結果 return result; };
分治算法常常和遞歸一塊使用,所謂分治算法,顧名思義,分而治之,最基本的分之算法在歸併排序、快速排序都有用到。也就是將原問題劃分紅 n 個規模較小,而且結構與原問題類似的子問題,遞歸地解決這些子問題,而後再合併其結果,就獲得原問題的解。
- 分解:將原問題分解成一系列的子問題。
- 解決:遞歸地求解各個子問題,若子問題足夠小,則直接求解;
- 合併:將子問題的結果合併成原問題。
- 可分解:原問題與分解成的小問題具備相同的模式;
- 無關聯:原問題分解成的子問題能夠獨立求解,子問題之間沒有相關性,這一點是分治算法跟動態規劃的明顯區別。
- 終止條件:具備分解終止條件;
- 合併不能太複雜:能夠將子問題合併成原問題,而這個合併操做的複雜度不能過高,不然就起不到減少算法整體複雜度的效果了。
歡迎一塊兒加入到 LeetCode 開源 Github 倉庫,能夠向 me 提交您其餘語言的代碼。在倉庫上堅持和小夥伴們一塊兒打卡,共同完善咱們的開源小倉庫!
Github:https://github.com/luxiangqia...數組