如何在指数大列表中找到第 k 个最大元素?

Swi*_*ack 8 python arrays sorting algorithm

假设有n组实数:S[1], S[2], ..., S[n]。关于这些集合,我们知道两件事:

  1. 每个集合 S[i] 正好有 3 个元素。

  2. 每个集合 S[i] 中的所有元素都是 [0, 1] 范围内的实数。(不过,我不知道这个细节是否对解决方案有帮助)。

让我们考虑一组T可以表示为的所有数字,p[1] * p[2] * p[3] * ... * p[n]其中 p[i] 是 S[i] 的一个元素。T显然,这个集合有 3^n 个元素。

我的问题是,给定集合S[1], S[2], ..., S[n](1 <= n <= 30) 和一些 1 <= k <= 10 作为输入,我们能否以T比 O(3^n) 时间更快的速度找到第 k 个最大数?重要的是,我不仅需要第 k 大的数字,还p[1], p[2], p[3], ... , p[n]需要产生它的相应数字 ( )。

即使答案是否定的,我也很感激您提供有关如何使用启发式方法大致解决此问题的任何提示?我知道beam search,但也许你可以提出其他建议?即使对于波束搜索,也不清楚如何在这里以最佳方式实现它。

如果可以在小于 O(3^n) 的时间内通过算法获得确切的答案,如果您能指出解决方案,我将不胜感激。

Mat*_*ans 12

好吧,您知道最大的乘积是使用每个集合中最大因子的乘积。

此外,所有其他乘积都可以通过从较大的乘积开始,然后减少恰好在一组中选择的因子来形成。

这导致了一个简单的搜索:

  1. 将最大的产品放入最大优先级队列。

  2. 重复k次:

    一种。从优先队列中取出最大的产品 p

    湾 对于比 p 中选择的数字更小的每个集合,通过将该数字减少到该集合中的下一个较小的数字来生成乘积。如果之前没有看到这些因素选择,则将其添加到优先级队列中。

产品将按降序从队列中删除,因此您取出的第 k 个是第 k 个最大的。

复杂度约为 N*(k log kN),具体取决于您如何实现。

请注意,可能有多种方法可以选择生产相同产品的因素。该解决方案将这些方式视为不同的产品,即在找到第 k 个最大时计算每种方式。这可能是也可能不是您想要的。

  • 我做到了。固定的 :) (2认同)
  • “如果之前没有见过,那就把它加入优先队列。” - 这不太正确,因为即使产品与以前的产品重复,您仍然需要继续搜索该产品。 (2认同)
  • @user2357112supportsMonica。是的,我将每个不同的元素选择视为不同的,而不是每个实际的产品价值。 (2认同)
  • 这里的 N 是 3^n 的顺序(n 取自问题)? (2认同)