【问题标题】:Quick select with repeat values使用重复值快速选择
【发布时间】:2012-12-25 11:25:42
【问题描述】:

是否可以在 O(n) 中对多集执行搜索第 k 个元素(值可以重复)?

因为据我了解快速选择的想法,我必须使用一些枢轴对输入进行分区。然后我有 2 个数组,我选择用于递归搜索取决于我正在搜索的索引元素 + 两个数组的大小,例如:

1 7 8 5 3 2 4

假设枢轴是 4 我正在搜索第二大元素。所以分区后我可能会得到类似的订单

1 3 2 4 7 8 5

因为右子数组由 3 个元素组成,如果我是正确的,我仍然会尝试在右数组中找到第二大的元素?

但如果我以 8 为支点,我可能会得到类似的东西

1 3 2 7 5 4 8

因此我会尝试在左表中找到最大的元素(可能是线性的,但通常我会使用左子数组并搜索元素 - (|右子数组大小| + 1))

但是多重集呢?假设我有数组:

4 5 6 7 7 7 4 3 2 1

我的支点是 6 搜索第三大元素,分区后我收到:

4 5 3 2 4 1 6 7 7 7

所以如果我使用上面介绍的方法,我将尝试在右子数组上执行递归,而很明显第三个最大值是左侧的 5?

我想出的唯一解决方案是使用 BST、Set 等数据结构来 O(nlogn) 过滤掉重复。然后使用 O(n) 快速选择。但是总的来说它会给我非线性方法,这可以线性完成吗?


我还有一个额外的问题,如果不能分配内存怎么办?我能做的就是只使用本地整数+堆栈递归。这个问题可以在 O(n) 中解决吗?因为O(nlogn)可以通过排序+线性“遍历计数”来完成。

【问题讨论】:

    标签: algorithm selection multiset quickselect


    【解决方案1】:

    我认为这取决于您对“第 k 个最大元素”的解释。如果“第 k 个最大元素”的意思是“如果已排序,则该元素将在数组中的位置 k 处”,那么 quickselect 将无需修改即可工作。

    另一方面,如果您的意思是“数组中第 k 个最大的不同值”,那么您是正确的,未修改的快速选择将无法正常工作,如您的示例所示。但是,您可以修改算法,使其在预期的 O(n) 时间内工作,方法是将所有元素添加到哈希表中,然后遍历哈希表以获得每个不同值的副本。从那里,您可以在生成的数组上使用正常的快速选择算法,这将需要总共 O(n) 时间的预期。

    希望这会有所帮助!

    【讨论】:

    • 说实话我还没有考虑过HT。但它应该有效。无论如何,我也在等待其他建议。如果有的话:)
    • 我想稍微改变一下问题。当分配额外内存不是有效操作时,最快的方法是什么。我只能使用带有元素的开始数组(只能分配 O(1) 内存 + 递归堆栈)。是否可以在 nlogn 或 n 中完成。限制意味着我不能使用结构。
    • 好吧,我回答自己 O(nlogn) 可以通过简单地排序来完成 + 找出有多少邻居值在线性时间内发生变化。所以这是一个愚蠢的问题。但仍然是组合:没有额外的内存 + O(n) 可达?
    猜你喜欢
    • 2015-07-14
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 2011-05-28
    相关资源
    最近更新 更多