Leetcode 23. Merge k Sorted Lists
题目
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
思路
这道题目最简单直接的解法为将k个list中所有的元素拿出来放入List中,并对这个大的List进行排序。但是,这种方法时间复杂度达到了O(nlog(n)), 而且我们完全没有巧妙利用sorted这个条件。
结合每个list已经被排好序这个特点,我们可知前k个元素(每个list的head)为所有元素中相对较小的k个,且所有元素中的最小元素必在此k个之中。由此,我们 可以比较这k个元素,并把最小的拿出来,作为我们返回列表的第一个元素。值得注意的是,第二小的元素不一定出现在剩下的k-1元素中。它可能仅仅比刚才第一小的元素大, 但是比刚才k-1个元素要小。因此,我们需要把最小元素所在列表的下一个元素拿出来,和剩下的k-1个元素比较,选出最小的,作为我们返回列表的第二个元素。我们 会重复这个过程,直至把所有元素全部排好顺序。
如何在k个元素中找到最小的呢?我们可以使用PriorityQueue,它在任意时间仅储存至多k个元素。
解答
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> pq = new PriorityQueue<ListNode>((n1, n2) -> n1.val - n2.val);
// Put all k-smallest heads into pq
for (ListNode node : lists) {
if (node != null) pq.offer(node);
}
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (! pq.isEmpty()) { // store at most k elements
// Insert the curr-smallest to the list
ListNode n = pq.poll();
curr.next = new ListNode(n.val);
curr = curr.next;
// Add new node into pq to keep pq's size as k
if (n.next != null) pq.offer(n.next);
}
return dummy.next;
}
}
Complexity Analysis
Time Complexity: O(nlog(k)). PriorityQueue最多有k个元素,因此插入需要O(log(k))的时间。我们都需要把每个元素装进PriorityQueue,因此总共需要O(nlog(k)).
Space Complexity: O(k). PriorityQueue占用额外空间储存k个元素。
拓展
我们之间做过Merge 2 Sorted List这道题目。我们能把它的思想运用到这道题目吗?需要做哪些改变? 显然不能直接进行(k - 1)次merge 2 sorted list,我们需要使用Divide and Conquer的思想。
Last updated
Was this helpful?