23. 合并K个升序链表
题目描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
输入输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 输入: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 = [[]] 输出:[]
|
基本思路
方法一:最愚蠢的方法 利用剑指 Offer 25. 合并两个排序的链表 全部两两合并得到结果
时间复杂度:假设每个链表的最长长度为n 第一次合并res长度为n
第二次2n
第i次in
则$O(n + (i-1)\times n) = O(in)$ 那么总的时间代价是$O(\sum_{i=1}^k(i \times n)) = O(\frac{(1+k)\times k}{2} \times n) = O(k^2n)$
最终可得 时复:$O(k^2n)$ 空复:$O(1)$
方法二:利用优先级队列 类似构建小顶堆的意思 保持队列头的结点数字最小
考虑优先队列中的元素不超过 $k$ 个,那么插入和删除的时间代价为 $O(logk)$,这里最多有 $kn$ 个点,对于每个点都被插入删除各一次,故总的时间代价即渐进时间复杂度为 $O(kn \times \log k)$。
空复:这里用了优先队列,优先队列中的元素不超过 k 个,故渐进空间复杂度为 $O(k)$。
1 2 3 4
| 运行45行之后 PriorityQueue: 三个节点 [1,1,2] dummy -> 1(p在这儿) if(p.next != null) queue.add(p.next); 运行后因为1(p) -> 4 重新将4丢入PriorityQueue的小根堆中
|
最终可得:时复:$O(kn \times \log k)$ 空复:$O(k)$
java实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| class Solution { public ListNode mergeKLists(ListNode[] lists) { int n = lists.length; ListNode res = null; for(int i = 0; i < n; i++) { res = merge2Lists(res, lists[i]); } return res; }
public ListNode merge2Lists(ListNode l1, ListNode l2) { ListNode res = new ListNode(0), cur = res; while(l1 != null && l2 != null){ if(l1.val < l2.val){ cur.next = l1; l1 = l1.next; } else{ cur.next = l2; l2 = l2.next; } cur = cur.next; } cur.next = l1 != null ? l1 : l2; return res.next; } }
class Solution { public ListNode mergeKLists(ListNode[] lists) { if(lists == null || lists.length == 0) return null; PriorityQueue<ListNode> queue = new PriorityQueue<>(lists.length, new Comparator<ListNode>() { @Override public int compare(ListNode o1, ListNode o2) { if(o1.val < o2.val) return -1; else if (o1.val == o2.val) return 0; else return 1; } }); ListNode dummy = new ListNode(0); ListNode p = dummy; for(ListNode list:lists){ if(list != null) queue.add(list); } while(!queue.isEmpty()){ p.next = queue.poll(); p = p.next; if(p.next != null) queue.add(p.next); } return dummy.next; } }
|