合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
分而治之
最快的做法
//分治
public ListNode mergeKLists(ListNode[] lists) {
if (lists==null || lists.length==0) return null;
return merge(lists, 0, lists.length-1);
}
private ListNode merge(ListNode[] lists, int left, int right){
if (left==right) return lists[left];
int mid = left + (right-left)/2;
ListNode l1 = merge(lists, left, mid);
ListNode l2 = merge(lists, mid+1, right);
return mergeTwoLists(l1, l2);
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2){
ListNode dummyHead = new ListNode(-1);
ListNode cur = dummyHead;
while (l1!=null && l2!=null){
if (l1.val<=l2.val){
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1==null? l2:l1;
return dummyHead.next;
}
最小堆
public ListNode mergeKLists(ListNode[] lists) {
if (lists==null || lists.length==0) return null;
PriorityQueue<ListNode> minHeap = new PriorityQueue<>(((o1, o2) -> o1.val-o2.val));
ListNode dummyHead = new ListNode(-1);
ListNode cur = dummyHead;
for (ListNode node : lists){
if (node!=null) minHeap.add(node);
}
while (!minHeap.isEmpty()){
cur.next = minHeap.poll();
cur = cur.next;
if (cur.next!=null) minHeap.add(cur.next);
}
return dummyHead.next;
}
逐个合并
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length==0) return null;
ListNode ret = new ListNode(-1);
for (int i = 1;i<lists.length;i++){
lists[0] = mergeTwoLists(lists[0], lists[i]);
}
return lists[0];
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2){
ListNode dummyHead = new ListNode(-1);
ListNode cur = dummyHead;
while (l1!=null && l2!=null){
if (l1.val<=l2.val){
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1==null? l2:l1;
return dummyHead.next;
}
632

被折叠的 条评论
为什么被折叠?



