递归
class Solution {
public ListNode mergeKLists(ListNode[] lists){
return mergeKLists(lists, 0);
}
public ListNode mergeKLists(ListNode[] lists, int left){
if (left >= lists.length){
return null;
}
if (left == lists.length - 1){
return lists[left];
}
/**
* 递归
* 假设lists[1, length - 1]的链表已经排好序,且返回头节点list
* 最后只用让lists[0]合并进最终的链表
*/
ListNode list = mergeKLists(lists, left + 1);
/**
* 定义最终链表的虚拟头节点
* 然后依次拿出两个链表的元素比较,始终指向较小的那个节点
*/
ListNode dummyHead = new ListNode();
ListNode prev = dummyHead;
ListNode cur = lists[left];
while (cur != null && list != null){
if (cur.val < list.val){
prev.next = cur;
cur = cur.next;
}
else {
prev.next = list;
list = list.next;
}
prev = prev.next;
}
/**
* 一旦有一个链表空了,直接指向剩余的链表
*/
prev.next = cur == null ? list : cur;
return dummyHead.next;
}
}
/**
* 时间复杂度 O(nlogn)
* 空间复杂度 O(n)
*/
优先队列
class Solution {
public ListNode mergeKLists(ListNode[] lists){
ListNode dummyHead = new ListNode();
ListNode prev = dummyHead;
PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
@Override
public int compare(ListNode o1, ListNode o2) {
return o1.val - o2.val;
}
});
/**
* 将每个子链表的头节点放进队列
* 按照节点的大小升序排列
*/
for (int i = 0; i < lists.length; i++) {
if (lists[i] != null) {
pq.add(lists[i]);
}
}
/**
* 然后每次让最小的节点出队,作为总链表的下一个节点,然后将其下一个节点入队,继续比较
*/
while (!pq.isEmpty()){
ListNode temp = pq.poll();
prev.next = temp;
prev = prev.next;
temp = temp.next;
if (temp != null) {
pq.add(temp);
}
}
return dummyHead.next;
}
}
/**
* 时间复杂度 O(nlogn)
* 空间复杂度 O(k)
*/
https://leetcode-cn.com/problems/merge-k-sorted-lists/