如何解决使用合并 2 个排序链表的概念合并 k 个排序链表的时间复杂度是多少?
如果我使用合并2个排序链表的算法,我想知道merging k sorted lists
的真实时间复杂度。
我曾在某处看到时间复杂度为 O(nk) 而某处为 O(nk^2)。 (k 是排序列表的数量,n 是列表中元素的数量)。 所以我对这个问题的时间复杂度感到困惑。
请告诉我这个问题的真实时间复杂度。
解决方法
如果我使用合并2个排序链表的算法,我想知道合并?排序列表的真实时间复杂度。
有多种算法可供选择。
我们将?定义为一个排序列表中值的(最大)数量,因此值的总数以??为界。
朴素算法
此算法合并前两个列表,然后将结果与第三个列表合并,然后将结果与第四个列表合并,等等。
这个算法需要执行 ?−1 次合并,每次合并将比前一个合并涉及 ? 更多的项目。第一次合并涉及两个?元素的列表,所以是O(2?)
因此我们有以下关系?:
?(2) = O(2?)
?(?) = ?(?−1) + O(??)
所以:
?(?) = O(?∑?=2..??) = O(??²)
最后一步使用triangular numbers的公式
分而治之的算法
(二进制)分治算法定义了只有 2 个列表时的基本情况,并将它们与已知算法合并。在所有其他情况下,它合并来自递归的两个列表。这确实是 merge sort 使用的原则。
现在递推关系如下:
?(2) = O(2?)
?(?) = 2?(?/2) + O(??)
如果我们将这个关系展开一次,我们得到:
?(?) = 2(2?(?/4) + O(??/2)) + O(??) = 4?(?/4) + O(??) + O(??) + O(p)
如果再次展开:
?(?) = 8T(?/8) + O(3??)
log2? − 1 次扩展后:
?(?) = (?/2)?(2) + O(??log?)
代入?(2),我们得到:
?(?) = O(??) + O(??log?) = O(??log?)
基于堆的算法
当您创建一个二进制最小堆时,其中每个条目都是一个链表,由其第一个节点的值作为键,然后您可以重复从具有最小元素的堆中拉出列表,从该列表中提取该元素,然后将该列表再次插入堆中,它将根据新键找到它的位置(因为它现在少了一个节点)。如果列表变为空,则不再将其插入堆中。
构建堆的成本为 O(?)。一次堆提取和插入成本 O(log?)。有??提取要做,所以复杂度是O(?) + O(??log?) = O(??log?)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。