题目
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
测试案例
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
思路
使用最小堆进行多路归并,堆中存放的元素是每一个有序链表。
排序的比较方法是链表头节点的值。
每次从堆中取出最小值后,取出头结点。当链表剩余部分非空时,就将其放入堆中。将头结点放入结果队列的尾部。
具体实现
-
由于 java 中有数据结构 PriorityQueue(优先级队列),所以利用它来实现。创建优先级队列时,传入一个比较器即可。
-
然后依次将每个非空链表放入队列中。
-
接下来,只要队列非空,就从中取出最小值的链表。取出头结点,剩余部分非空时,放回队列,将头结点放入结果队列尾部。
-
优先级队列为空时,将结果队列尾节点的 next 置为空,注意,此时 tail 可能为空。需要先判断。
代码如下
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode head = null, tail = null;
//建立一个优先级队列
PriorityQueue<ListNode> heap = new PriorityQueue<>((n1, n2)->{
return n1.val - n2.val;
});
int num = lists.length;
//依次放入每一个非空链表
for(int i = 0; i < num; i++){
if(lists[i] != null){
heap.offer(lists[i]);
}
}
ListNode cur;
while(!heap.isEmpty()){
cur = heap.poll();
if(cur.next != null){
heap.offer(cur.next);
}
if(head == null){
head = cur;
}
else{
tail.next = cur;
}
tail = cur;
}
if(tail != null){
tail.next = null;
}
return head;
}
}