原题链接:https://oj.leetcode.com/problems/merge-k-sorted-lists/
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
这篇讲得很好:http://blog.csdn.net/linhuanmars/article/details/19899259
Suppose we have k lists,the total number of nodes is n, 则
方法I:同上一题。Perform k-1 merge steps to merge k lists. In each step, do n comparisons to merge two lists.
Time: O(nk). Space: O(1)
public class Solution {
public ListNode mergeKLists(List<ListNode> lists) {
if(lists.size() == 0) return null;
ListNode p = lists.get(0);
for(int i = 1; i < lists.size(); i++){
p = mergeTwoLists(p, lists.get(i));//p is updated for every merge
}
return p;
//for(int i = 0; i < lists.size(); i++){
//for(int j = i+1; j < lists.size(); j++){
// mergeTwoLists(lists.get(i), lists.get(j));
//}
//}
}
private ListNode mergeTwoLists(ListNode l1, ListNode l2){
ListNode head = new ListNode(-1);
ListNode p = head;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
p.next = l1;
l1 = l1.next;
}
else{
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if(l1 != null) p.next = l1;
else p.next = l2;
return head.next;
}
}
This solution generated Time Limit Exceed for large dataset in leetcode.
方法II: MergeSort的思路.
Since T(k) = 2T(k/2) + O(n) (why?), we have T(k) = O(nlogk) by the Master Theorem (why?)
Time: O(nlogk), Space: O(logk)
public class Solution {
public ListNode mergeKLists(List<ListNode> lists) {
if(lists == null || lists.size() == 0) return null;
return helper(lists, 0, lists.size()-1);
}
private ListNode helper(List<ListNode> lists, int l, int r){
if(l < r){//must check if l < r
int m = (l+r)/2;
return merge(helper(lists, l, m), helper(lists, m+1, r));
}
return lists.get(l);
}
private ListNode merge(ListNode l1, ListNode l2){
ListNode head = new ListNode(-1);
ListNode p = head;
while(l1 != null && l2 != null){
if(l1.val <= l2.val){
p.next = l1;
l1 = l1.next;
}
else{
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if(l1 != null) p.next = l1;
else p.next = l2;
return head.next;
}
}
方法III: 维护一个大小为k的heap (PriorityQueue)的最小堆(Note: Topk 最大元素那题,要建最小堆。和这里相反。Because in top-k, what we need is the elements in the heap. We add the elements in the list only if they are larger than the root of the heap. However, in this question, heap is only a tool for us to sort our element. )。每次从堆顶取一个最小元素,然后从该元素所在的list里取下一个元素,放入堆。
Time: O(nklogk), Space: O(k)
http://www.programcreek.com/2013/02/leetcode-merge-k-sorted-lists-java/
public class Solution {
public ListNode mergeKLists(ArrayList<ListNode> lists) {
if (lists.size() == 0)
return null;
//PriorityQueue is a sorted queue
PriorityQueue<ListNode> q = new PriorityQueue<ListNode>(lists.size(),
new Comparator<ListNode>() {
public int compare(ListNode a, ListNode b) {
if (a.val > b.val)
return 1;
else if(a.val == b.val)
return 0;
else
return -1;
}
});
//add first node of each list to the queue
for (ListNode list : lists) {
if (list != null)
q.add(list);
}
ListNode head = new ListNode(0);
ListNode prev = head;
while (q.size() > 0) {
ListNode temp = q.poll();
prev.next = temp;
//keep adding next element of each list
if (temp.next != null)
q.add(temp.next);
prev = prev.next;
}
return head.next;
}
}
问题:
ListNode head = new ListNode(0);
ListNode prev = head;
写成
ListNode head = queue.poll();
ListNode p = head;
会出现错误:
Input: | [{1,2,2},{1,1,2}] |
Output: | {1,1,1,2} |
Expected: | {1,1,1,2,2,2} |