思路
利用java中提供的优先级队列(默认的小根堆)可以解决此问题
- 首先将所有链表头加入优先级队列
- 然后每次遍历取出小根堆中的最上链表(元素值最小)
- 然后将该节点加入结果链表中
- 将取出的这个链表后移,如果不为空则继续加入堆中;如果为空(该链表全为空)则直接跳出循环遍历其他链表
- 将结果链表也后移,为下一个节点的加入做准备
- 最终返回结果链表真正的头结点即可
代码实现(java)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
ListNode dummy = new ListNode(0);
public ListNode mergeKLists(ListNode[] lists) {
ListNode res = dummy;
if(lists == null) return null;
// 小根堆
PriorityQueue<ListNode> head = new PriorityQueue<>((ListNode o1, ListNode o2) -> {
return o1.val - o2.val;
});
// 将每个链表的头结点存入head中
for(int i = 0; i < lists.length; i++) {
if(lists[i] != null) {
head.offer(lists[i]);
}
}
while(head.isEmpty()) return null;
// 利用小根堆的特性,最小的元素放在了头部
// 我们每次都将小根堆的头元素取出,然后接到结果链表中
// 让取出的链表后移,结果链表后移
// 最后判断取出链表后移之后还有没有元素,如果没有了就继续循环,取别的链表元素
// 知道所有链表为空,堆为空,退出即可
while(head.peek() != null) {
ListNode cur = head.poll();
dummy.next = cur;
dummy = dummy.next;
cur = cur.next;
if(cur == null) continue;
head.offer(cur);
}
return res.next;
}
}