gpt4 book ai didi

algorithm - 合并 k 个列表的最佳方式是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:25:40 26 4
gpt4 key购买 nike

假设您有一个合并函数,它将在 O(s1+s2) 时间内合并(找到并集)大小为 s1 和 s2 的两个列表 L1 和 L2。合并大小为 s1、s2、...、sk 的 k 个列表的最佳方法是什么?

我认为我们应该首先对 s1, ..., sk 进行排序,然后对对应于最小两个大小的前两个列表进行排序。当这些被合并时,我们找到它们的大小在排序的大小列表中的位置并继续这个过程,直到我们最终得到一个列表。

我在两件事上遇到了麻烦:1. 这是否确实是最优的(是否有另一种方法可以更快地返回)? 2. 合并时列表大小发生变化,如何分析运行时间?

最佳答案

恰好与为由k 的字母表组成的字符串寻找最佳可变长度位编码的问题相同。具有已知频率的符号 s<sub>1</sub>, s<sub>2</sub>, … s<sub>k</sub> .你的算法正是Huffman algorithm ,并且您会在任何有关算法的教科书(以及许多在线资源)中找到最优性证明,因为它是具有简单正确性证明的贪婪算法的经典案例。

双向合并的重复应用会产生一个二叉树,其中每个节点都是一个合并。给定那棵树,任何叶子对整体合并总成本的贡献是该叶子的权重乘以它在树中的深度。 (每个节点都是一个合并,叶子中的值恰好参与从叶子到根的路径中的合并;此类合并的数量是树中叶子的深度。)类似地 - 或相同地 - -,一个哈夫曼编码的比特串的总长度是符号的权重(频率)与构造树中该符号对应的叶子深度的乘积之和。

算法的一个小改进(编写霍夫曼树构建器的人经常错过):有必要对权重进行排序 s<sub>1</sub>, s<sub>2</sub>, … s<sub>k</sub> ,但这是唯一需要的类型。从那里开始,算法总是选择两个最低的节点并将它们相加。结果总和的大小必须是单调非递减的(如果总和小于前一个总和,则前一个总和不可能是两个最小元素的总和)。所以你可以把总和放在一个队列中;在每一步中,您都可以从已排序的叶子数组或(隐式)已排序的节点队列中选择两个最小的元素。

这可以通过用节点队列覆盖叶数组来进一步优化。 (然后队列从数组底部向顶部增长;证明队列顶部永远不会超过数组底部是相当简单的。)

关于algorithm - 合并 k 个列表的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26199864/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com