LeetCode #23 Merge k Sorted Lists (H)

时间:2022-03-21 21:03:03

[Problem]

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

 

[Analysis]

这题一上来,就会想到之前做过的Merge Two Sorted Lists。但是如果单纯地不断将新的list merge进结果,复杂度是非常高的,因为仔细想想就会发现在这个过程中结果里已经merge过的元素需要被重新排序,而这一部分无用功是可以通过使用合理的技巧优化的。这里需要用到的是heap数据结构。想到heap之后的步骤就比较简单了,只需要将所有list head放进heap,每次取出顶部的一个链接到结果里,并将它的next放进heap(假如存在),直至heap为空也就是所有元素都访问过一遍。其中存取元素以及链接的复杂度都是O(1),而heap存入新元素的复杂度是O(log(k)),于是整个算法的复杂度就是O(log(k) * n),n为所有list里元素的个数之和。

*注意有很多null case需要判断。

*在Java里面heap的implementation是PriorityQueue。

 

[Solution]

 

import java.util.Comparator;
import java.util.PriorityQueue;

public class Solution {
    public ListNode mergeKLists(ListNode[] lists) {        
        int size = lists.length;
        if (size == 0) {
            return null;
        }
        
        if (size == 1) {
            return lists[0];
        }
        
        PriorityQueue<ListNode> heap = new PriorityQueue<ListNode>(
            2, 
            new Comparator<ListNode>() {
                @Override
                public int compare(ListNode node1, ListNode node2) {
                    return node1.val - node2.val;
                }
            }
        );
        
        for (ListNode node : lists) {
            if (node != null) {
                heap.add(node);
            }
        }                
        
        ListNode head = null;
        ListNode cur = null;
        
        while (!heap.isEmpty()) {
            ListNode node = heap.poll();                        
            
            if (node.next != null) {
                heap.add(node.next);
            }
            
            if (head == null) {
                head = node;
                cur = node;
            } else {
                cur.next = node;
                cur = cur.next;
            }
        }
        
        return head;
    }    
}