如果本文章有不懂的,请进入预习链接:优先级队列_加瓦不加班的博客-CSDN博客
这道题目之前解答过,现在用刚学的优先级队列来实现一下
题目中要从小到大排列,因此选择用小顶堆来实现,自定义小顶堆如下
//小顶堆的操作与大顶堆的操作基本相似 但是我们这里就没有实现E,我们直接利用Node的val来实现
public class MinHeap {
/*
min
1->4->5->null
1->3->4->null
2->6->null
小顶堆
1 2 4
新链表
s->1
*/
ListNode[] array;
int size;
public MinHeap(int capacity) {
array = new ListNode[capacity];
}
public void offer(ListNode offered) {
int child = size++;
int parent = (child - 1) / 2;
while (child > 0 && offered.val < array[parent].val) {
array[child] = array[parent];
child = parent;
parent = (child - 1) / 2;
}
array[child] = offered;
}
public ListNode poll() {
if (isEmpty()) {
return null;
}
swap(0, size - 1);
size--;
ListNode e = array[size];
array[size] = null; // help GC
down(0);
return e;
}
private void down(int parent) {
int left = 2 * parent + 1;
int right = left + 1;
int min = parent;
if (left < size && array[left].val < array[min].val) {
min = left;
}
if (right < size && array[right].val < array[min].val) {
min = right;
}
if (min != parent) {
swap(min, parent);
down(min);
}
}
private void swap(int i, int j) {
ListNode t = array[i];
array[i] = array[j];
array[j] = t;
}
public boolean isEmpty() {
return size == 0;
}
}
代码:
public class E01Leetcode23 {
public ListNode mergeKLists(ListNode[] lists) {
// 1. 使用 jdk 的优先级队列实现
// PriorityQueue<ListNode> queue = new PriorityQueue<>(Comparator.comparingInt(a -> a.val));
// 2. 使用自定义小顶堆实现
MinHeap queue = new MinHeap(lists.length);
//将链表加入到小顶堆
for (ListNode head : lists) {
//注意:当List传入的是空
if (head != null) {
queue.offer(head);
}
}
//新链表创建哨节点
ListNode s = new ListNode(-1, null);
ListNode p = s;
//不断从堆顶移除最小元素,加入新链表
while (!queue.isEmpty()) {
ListNode node = queue.poll();
p.next = node;
p = node;
if (node.next != null) {
queue.offer(node.next);
}
}
return s.next;
}
}
测试用例:
//用例测试
public static void main(String[] args) {
ListNode[] lists = {
ListNode.of(1, 4, 5),
ListNode.of(1, 3, 4),
ListNode.of(2, 6),
null,
};
ListNode m = new E01LetCode23().mergeKLists(lists);
System.out.println(m);
}
提问:
能否将每个链表的所有元素全部加入堆,再一个个从堆顶移除?
回答:
可以是可以,但对空间占用就高了,堆的一个优点就是用有限的空间做事情