两个大小为 n 的数据库中的第 n 个最小数字,每个数据库都使用分而治之 [关闭]

Posted

技术标签:

【中文标题】两个大小为 n 的数据库中的第 n 个最小数字,每个数据库都使用分而治之 [关闭]【英文标题】:nth smallest number among two databases of size n each using divide and conquer [closed] 【发布时间】:2011-02-01 15:10:33 【问题描述】:

我们有两个大小为 n 的数据库,其中包含不重复的数字。所以,我们总共有 2n 个元素。它们可以通过一次查询一个数据库来访问。该查询是这样的,您给它一个 k 并返回该数据库中的第 k 个最小条目。我们需要在 O(log n) 查询的所有 2n 个元素中找到第 n 个最小的条目。

这个想法是使用分而治之,但我需要一些帮助来思考这个问题。谢谢!

【问题讨论】:

【参考方案1】:

我前不久在资格考试中看到了这个问题,它闻起来像家庭作业问题。因此,我只提出两个建议:

研究二分搜索,仔细注意循环不变量的精确性质。 Jon Bentley 的书Programming Pearls 有很好的解释

尝试为二分搜索推广不变量。

绘制各种特殊情况的图片:

DB1 中的每个数字都小于 DB2 中的每个数字 反之亦然 DB1 等于 DB2 DB2 中的每个数字都是 DB1 中相应数字的两倍

这是一个相当困难的问题;如果你直接去证明正确性,你会更轻松。

【讨论】:

@Tom:这种事情对于教授来说是相当典型的。当一位教授写下两条建议时,他想到了第三条。我想我会离开它:-) @Tom:两个建议:恐惧和惊喜,以及无情的效率。 @Steve, @Tom: 以及对教皇近乎***的忠诚!!!【参考方案2】:

这就是我的想法。既然这是一个教育问题,我建议你停止阅读,如果其中任何一点让你认为,“啊哈,我没想到,我可以自己按照这些思路进一步思考”。

1) 与 sdcwc 相同的观察结果:对于它是从 0 还是从 1 开始可能会有轻微的疑问,数据库可以被认为是一个排序数组。我要求元素 0,我得到最小的。我要 12 个,我得到第 13 个最小的。等等。我发现这更容易可视化。

2) 我们知道我们正在寻找一个 O(log n) 算法。这意味着粗略地说,我们正在寻找以下两件事之一:

要么我们从计算最小元素开始,然后计算第 2 小、第 4 小、第 8 等,直到达到我们想要的大小,每一步都在恒定时间内。这对我来说听起来不太乐观。

或者我们从一个大小为 n 的问题开始,然后我们执行一些常数时间操作,这允许我们通过解决大小为 n/2 的问题来解决原始问题。显然我们可以在常数时间内解决n=1的问题,完成算法。这听起来更有道理。

实际上不一定每次都必须是 n/2。它可能是 n/3 或 999*n/1000,结果仍然是 O(log n)。不过先找 n/2 也没什么坏处。

3) 我们将如何减少这样的问题?好吧,如果我们可以从一个数组或另一个数组的开头打折/删除 m 个元素小于第 k 个最小的元素,那么我们可以找到结果数组对中第 (km) 个最小的元素,它将是原始数组中的第 k 个最小的。

4) 最后,突破性观察是,如果数组 A 的第 m 个最小元素小于数组 B 的第 m 个最小元素,那么 A 的第 m 个元素不可能是两者中的第 (2m) 个最小元素数组组合。它小于那个(或相等的值:我不确定“无重复”是否意味着“每个数据库中没有重复”或“合并的数据库之间没有重复”),因为最多有 2*(m- 1) 两个数组组合中的元素严格小于它。

除非我犯了错误,否则剩下的就是编码。当 k 为奇数时,通过一个小的额外参数来解释 off-by-1,这个解决方案实际上是 O(log k),这是 O(log n),因为 k

【讨论】:

【参考方案3】:

提示:

请注意,您的“数据库”实际上是两个已排序的数组。 从数组的“中间”获取元素并进行比较。比较的结果可能允许您“排除”某些部分。

【讨论】:

以上是关于两个大小为 n 的数据库中的第 n 个最小数字,每个数据库都使用分而治之 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

旋转数组的最小数字

codevs 1031 质数环

1031 质数环

经典算法冒泡排序

1031 质数环

codevs1031 质数环