6.3 Merge k Sorted Lists

原题链接: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}
为什么?@9.1.2014

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值