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;
    }
}
原文地址:https://www.cnblogs.com/reboot329/p/6213795.html