23. 合並K個排序鏈表
阿新 • • 發佈:2018-07-15
null htm pan || 有序鏈表 表頭 pub 相關 復雜度
知乎ID: 碼蹄疾
碼蹄疾,畢業於哈爾濱工業大學。
小米廣告第三代廣告引擎的設計者、開發者;
負責小米應用商店、日歷、開屏廣告業務線研發;
主導小米廣告引擎多個模塊重構;
關註推薦、搜索、廣告領域相關知識;
題目
合並 k 個排序鏈表,返回合並後的排序鏈表。請分析和描述算法的復雜度。
示例:
輸入:
[
1->4->5,
1->3->4,
2->6
]
輸出: 1->1->2->3->4->4->5->6
分析
前面已經做過兩個有序鏈表的合並,只要采用二分,分而治之,兩兩合並即可。時間復雜度方面,合並兩個鏈表的長度的時間復雜度是o(min(m, n)),其中m,n分別是鏈表的長度。二合並的長度是o(logk)的時間復雜度。所以整體的時間復雜度為o(klogn)
Code
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) { return l2; }if (l2 == null) { return l1; } ListNode merged = null; ListNode head = null; while (l1 != null && l2 != null) { if (head == null) { if (l1.val < l2.val) { merged = l1; l1 = l1.next; }else { merged = l2; l2 = l2.next; } head = merged; continue; } if (l1.val < l2.val) { merged.next = l1; l1 = l1.next; } else { merged.next = l2; l2 = l2.next; } merged = merged.next; } while (l1 != null) { merged.next = l1; l1 = l1.next; merged = merged.next; } while (l2 != null) { merged.next = l2; l2 = l2.next; merged = merged.next; } return head; } public ListNode mergeHelper(ListNode[] lists, int low, int high) { if (low < high) { int mid = (low + high) / 2; ListNode leftList = mergeHelper(lists, low, mid); ListNode rightList = mergeHelper(lists, mid + 1, high); return mergeTwoLists(leftList, rightList); } return lists[low]; } public ListNode mergeKLists(ListNode[] lists) { if (lists == null || lists.length == 0) { return null; } return mergeHelper(lists, 0, lists.length - 1); } }
拓展
合並兩個有序鏈表,之前采用的是非遞歸的解法。感覺代碼有點長,可以采用遞歸的解法,縮短代碼量。合並的時候選最小的元素,鏈表頭指針後移動,遞歸合並即可。
public class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null && l2 == null) { return null; } if (l1 == null) { return l2; } if (l2 == null) { return l1; } ListNode merged; if (l1.val > l2.val) { merged = l2; l2 = l2.next; merged.next = mergeTwoLists(l1, l2); } else { merged = l1; l1 = l1.next; merged.next = mergeTwoLists(l1, l2); } return merged; } }
相關題目
21. 合並兩個有序鏈表
23. 合並K個排序鏈表