最后更新
一刷。
这个题不像是一刷,Hedvig的面经题。
K largest之类的题一般都可以用priority queue。
这里PQ里存的是,每个LIST的首NODE。
可以考虑divide and conquer,中文好像叫分治递归?这里的K个sorted lists已经给我们分治好了,我们负责递归就可以了。。
Time Complexity:
开始进入pq是K个lists,所以是O(klgk)。然后每个LIst有n个nodes的话,要poll()总共nk次,但是PQ的大小一直是K,所以是O(nklgK),最后是
O((nk+k)lgK) = O(k(n-1)lgk) = O (nk lg k)
Space: O(k)
这里的N是总共
public class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) return null;
ListNode dummy = new ListNode(0);
PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>(new Comparator<ListNode>() {
public int compare(ListNode a, ListNode b) {
return Integer.compare(a.val, b.val);
}
});
for (ListNode node : lists) {
if (node != null) {
pq.offer(node);
}
}
ListNode temp = dummy;
while (!pq.isEmpty()) {
temp.next = pq.poll();
temp = temp.next;
if (temp.next != null) {
pq.offer(temp.next);
}
}
return dummy.next;
}
}
另一种做法是divide and conquer
每次把2个LIST组合成1个就行了。。
Time Complexity:
T(k) = 2T(k/2) + O(nk)
= O(nk lgK)
(https://zh.wikipedia.org/wiki/主定理)
Space Complexity:
O(lgK) for recursion stack.
public class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) return null;
return helper(0, lists.length - 1, lists);
}
public ListNode helper(int l, int r, ListNode[] lists) {
if (l < r) {
int m = l + (r - l)/2;
return merge(helper(l, m, lists), helper(m+1, r, lists));
} else if (l == r) {
return lists[l];
} else {
return null;
}
}
public ListNode merge(ListNode l1, ListNode l2) {
if (l1 == null || l2 == null) {
return l1 == null? l2 : l1;
}
ListNode dummy = new ListNode(0);
ListNode temp1 = l1;
ListNode temp2 = l2;
ListNode temp = dummy;
while (temp1 != null && temp2 != null) {
if (temp1.val < temp2.val) {
temp.next = temp1;
temp1 = temp1.next;
} else {
temp.next = temp2;
temp2 = temp2.next;
}
temp = temp.next;
}
if (temp1 == null) {
temp.next = temp2;
} else {
temp.next = temp1;
}
return dummy.next;
}
}