----------------------------------------------本题链接----------------------------------------------
题目描述
合并 k 个已排序的链表并将其作为一个已排序的链表返回。分析并描述其复杂度。
示例
输入
[{1,2,3},{4,5,6,7}]
返回值
{1,2,3,4,5,6,7}
思路
合并有序链表的升级版
基础版合并有序链表代码如下
public class Solution {
/**
*
* @param l1 ListNode类
* @param l2 ListNode类
* @return ListNode类
*/
public ListNode mergeTwoLists (ListNode l1, ListNode l2) {
if(l1 == null) return l2;
if(l2 == null) return l1;
ListNode res = new ListNode(-1);
ListNode 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 ? l2 : l1;
return res.next;
}
}
这里可以考虑两两合并,也可以考虑用优先队列来做
优先队列则是:先把各链表头结点加入队列中,数值小的链表位于顶部。
有点类似于bfs的思想,顶部元素出队,则把它的链表元素加入队列,这样最终获得的链表就是有序的
算法过程
- 判断异常情况
- 初始化优先队列(最小堆)和虚拟头结点
- 将所有链表头结点加入队列中
- 取出队列顶部元素,并将顶部元素的链表加入队列
- 输出虚拟头结点下一节点
解答
public class Solution {
public ListNode mergeKLists(ArrayList<ListNode> lists) {
if(lists.size() == 0 || lists == null) return null;
Queue<ListNode> queue = new PriorityQueue<ListNode>((v1,v2) -> (v1.val-v2.val));
ListNode dummy = new ListNode(-1), cur = dummy;
for(ListNode node : lists){
if(node != null)
queue.offer(node);
}
while(!queue.isEmpty()){
cur.next = queue.poll();
cur = cur.next;
if(cur.next != null){
queue.offer(cur.next);
}
}
return dummy.next;
}
}