zoukankan      html  css  js  c++  java
  • 23. Merge k Sorted Lists

    最后更新

    一刷。

    这个题不像是一刷,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;
        }
    }
    
  • 相关阅读:
    符号修饰与函数签名、extern “C”
    WinInet单线程断点续传下载
    关掉"离开模式“,解决计算机无法进入睡眠状态
    链接库——动态链接库
    Google开源项目风格指南——类
    使用CURL读取HTTP数据到字符串或者文件中
    Wininet多线程断点续传下载
    contains
    [转]在linux下如何使用Makefile对fortran程序进行编译
    【转】一些解决变态数学公式的算法地址
  • 原文地址:https://www.cnblogs.com/reboot329/p/6213795.html
Copyright © 2011-2022 走看看