合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int len = lists.length;
if (len == 0) {
return null;
}
//排序方式为 a.val 比较大小
PriorityQueue<ListNode> priorityQueue = new PriorityQueue<>(len, Comparator.comparingInt(a -> a.val));
ListNode dummyNode = new ListNode(-1);
ListNode curNode = dummyNode;
for (ListNode list : lists) {
if (list != null) {
// 将头节点放入队列 自动排序
priorityQueue.add(list);
}
}
while (!priorityQueue.isEmpty()) {
// 优先队列非空才能出队 优先队列弹出一个
ListNode node = priorityQueue.poll();
// 当前节点的 next 指针指向出队元素
curNode.next = node;
// 当前指针向前移动一个元素,指向了刚刚出队的那个元素
curNode = curNode.next;
if (curNode.next != null) {
// 只有非空节点才能加入到优先队列中 curNode.next 将这个节点的下一个放入优先队列
priorityQueue.add(curNode.next);
}
}
return dummyNode.next;
}
}
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if(lists.length == 0){
return null;
}
return solve(lists, 0 ,lists.length - 1);
}
//解决问题
private ListNode solve(ListNode[] arr, int left, int right) {
if(left == right)
return arr[left];
int mid = (left + right) >> 1;
ListNode lNode = solve(arr, left, mid);
ListNode rNode = solve(arr, mid+1, right);
// 合并左右两个链表
return merge(lNode, rNode);
}
private ListNode merge(ListNode node1, ListNode node2){
if(node1 == null)
return node2;
if(node2 == null)
return node1;
// node1小于 右边的 node2数 将小的放到前面,比较下一个节点 和node2
if(node1.val < node2.val){
node1.next = merge(node1.next, node2);
return node1;
}else{
node2.next = merge(node1, node2.next);
return node2;
}
}
}