描述
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
分析
有两种主流思路:小顶堆,分治。此处题解为堆的方法。
堆的思路:把所有的结点加入到堆中,然后依次弹出,便是有序的。
堆解法的优化:开始只把每个链表的头结点加入到堆中,每次弹出堆顶元素,判断这个元素是否还有后继,有则加入,直到堆为空。相比于未优化的堆解法,使用的空间变小了。
优化的堆解法:
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode head = new ListNode(0);
ListNode cur = head;
Queue<ListNode> heap = new PriorityQueue<>(new Comparator<ListNode>(){
public int compare(ListNode a, ListNode b){
return a.val - b.val;
}
});
//lamdba表达式的小顶堆
//Queue<ListNode> heap = new PriorityQueue<>((a,b) -> a.val - b.val);
for(ListNode li : lists){
if(li != null){
heap.offer(li);
}
}
while(heap.size() > 0){
ListNode tmp = heap.poll();
cur.next = tmp;
cur= cur.next;
if(tmp.next != null){
heap.offer(tmp.next);
}
}
cur.next = null;
return head.next;
}
}
没有优化的堆解法
import java.util.*;
public class Solution {
public ListNode mergeKLists(ArrayList<ListNode> lists) {
ListNode head = new ListNode(0);
ListNode cur = head;
Queue<ListNode> heap = new PriorityQueue<>(new Comparator<ListNode>(){
public int compare(ListNode a, ListNode b){
return a.val - b.val;
}
});
for(ListNode li : lists){
while(li != null){
heap.offer(li);
li = li.next;
}
}
while(heap.size() > 0){
cur.next = heap.poll();
cur = cur.next;
}
cur.next = null;
return head.next;
}
}