题目是: 给定K个有序数组,将它们合并成一个数组并且有序, 需要考虑时间复杂度.
这也是leetcode上的第23道题,由合并两个数组延生而来.
K个数组合并
这里做个假设, 有序数组的个数为 L
所有数组中, 最长数组的长度为 N, 每个数组中的元素个数可以不等
很正常的会想到写二层for循环相邻两两进行合并,但时间复杂度肯定过不去
可以使用最小堆, python中很少情况会想到使用堆, 开始还以为python中没有, 顺便研究了下heap,具体思路为:
- 维护一个最小堆, 堆的个数等于链表个数, 为L
- 维护一个新链表,为D
- 初始化堆中的元素为每个链表的第一个元素
- 由最小堆的特性,堆的最顶层元素为最小值,每次取该最小值并记录该最小值所在有序链表的索引
- 将该最小值添加到D中
- 再把该最小值所在的链表的下一个元素入堆(如果存在的话)
- 循环4-6直到所有元素都已添加到D中
1 | import heapq |
通过索引来获取对应数组的下一个元素, 使用的非常巧妙
这里主要使用到了heapq跟deque,大家可以到官网查看这两个的用法
复杂度分析
- 时间复杂度: 由于每个元素都需要读取一次, 即最大次数为L*N, 将每一个元素插入最小堆中的复杂度为O(logL),即总的复杂度为O(L*NlogL)
- 空间复杂度为: 维护最小堆的大小,即 O(L)
在实际中的运用
在分布式任务聚合后需要按照时间顺序统一排序的场景下会有这个需要,linux下也有一些实现,可参照这篇文章