Merge K Sorted List

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

11/3 这道题也跟狗家的onsite有点像, 下面讲讲俺的思路:

之前的解法:

把这些lists两两merge, 知道最后只剩下一个list

public class Solution {
    public ListNode mergeKLists(List<ListNode> lists) {
         /*CAUTION: use a loop to remove throws an error
         http://stackoverflow.com/questions/8189466/java-util-concurrentmodificationexception
         */
         //if(lists.size() > 300)  return null;
          
         List<ListNode> remove = new ArrayList<ListNode>();
         for(int i= lists.size()-1; i>=0; i--){
             if(lists.get(i) == null){
                 lists.remove(i);
             }
         }
          
          
         ListNode tail = null, list = null;
         while( !lists.isEmpty() ){
             ListNode p = lists.get(0);
             ArrayList<Integer> rm = new ArrayList<Integer>();
             for(int i=0; i<lists.size(); i++){
                 ListNode node = lists.get(i);
                 if(node.val < p.val){
                     p = node;
                 }
             }
              
             for(int i=lists.size()-1; i>=0; i--){
                 if(lists.get(i).val == p.val){
                     rm.add(Integer.valueOf(i));
                 }
             }
              
             for(int j=0; j<rm.size(); j++){
                 int index = rm.get(j).intValue();
                 ListNode q = lists.get(index);
                 if(list == null){
                     list = q;
                 }else{
                     tail.next = q;
                 }
                 tail = q;
                 q = q.next;
                 if(q == null){
                     lists.remove(index);
                 }else{
                     lists.remove(index);
                     lists.add(q);
                 }
             }
              
              
              
         }
          
         return list;
          
    }
}

空间复杂度是O(1),

时间复杂度:

首先假设list 2i 和 list 2i+1 合并成list i, 时间是O(m), m是最长的一个list的长度, 一共有n/2个要合并, 假设没有空的list

然后是list 2i和list 2i+2 合并成list 2i, 时间是O(2m), 一共是n/4个需要合并

。。。

可以知道对于某一个ListNode, 会被访问lg(n)次, n是list的数量, 所以时间复杂度是O(Nlgn), N是所有node的数量


另一种解法是使用一个heap储存这些lists,每次得到min的时候都需要siftdown,所以时间复杂度是O(Nlgn)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public class Heap{
        public ListNode[] list;
        public int size = 0;
        public Heap(int n){
            list = new ListNode[n];
        }
        public boolean isEmpty(){
            return size == 0;
        }
        
        public void heapify(){
            for(int i=size-1; i>=0; i--){
                siftDown(i);
            }
        }
        
        public ListNode min(){
            ListNode head = list[0];
            list[0] = list[0].next;
            if(list[0] == null){
                swap(0,size-1);
                size--;
                siftDown(0);
            }else{
                siftDown(0);
            }
            
            head.next = null;
            return head;
        }
        
        private void siftDown(int from){
            int left = 2*from + 1;
            int right = left + 1;
            
            if(left >= size)    return;
            
            int min = from;
            if(left < size && list[left].val < list[min].val)       min = left;
            if(right < size && list[right].val < list[min].val)     min = right;
            swap(min,from);
            if(min != from)     siftDown(min);
        }
        
        private void swap(int i, int j){
            ListNode tmp = list[i];
            list[i] = list[j];
            list[j] = tmp;
        }
        
    }
    
    public ListNode mergeKLists(List<ListNode> lists) {
        /**
         * try solve with a heap
         */ 
        Heap heap = listToHeap(lists);
        if(heap.size == 0)    return null;
        
        ListNode ans = heap.min();
        ListNode prev = ans;
        while(!heap.isEmpty()){
            prev.next = heap.min();
            prev = prev.next;
        }
        return ans;
    }
    
    public Heap listToHeap(List<ListNode> lists){
        int len = lists.size();
        Heap heap = new Heap(len);
        int start = 0, end = len-1;
        for(ListNode list: lists){
            if(list != null){
                heap.list[start++] = list;
            }else{
                heap.list[end--] = null;
            }
        }
        heap.size = start;
        heap.heapify();
        return heap;
    }
    
    
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值