【问题标题】:algorithm of finding max of min in any range for two arrays在任何范围内为两个数组找到最大值的算法
【发布时间】:2018-01-02 23:37:23
【问题描述】:

假设我们有两个长度相等的整数数组,a_1, ..., a_nb_1, ..., b_n。对于任何给定的索引对ij1<=i<j<=n,我们需要找到a_k, ..., a_{l-1}, b_l, ..., b_{j-i+k}0<=k<=n-j+il 形式的任何序列的最小值的最大值可以是j-i+k+1,即该序列纯粹来自数组a。当k=0时,序列纯粹来自数组b

我们希望非常高效地对所有 ij 对执行此操作。

例子,给定

`a=[3,2,4,1]` and `b=[4,6,1,3]`
when `i=1, j=3`, the sequence can be
`[3,2,4]`, min is 2
`[3,2,1]`, min is 1
`[3,6,1]`, min is 1
`[2,4,1]`, min is 1
`[2,4,3]`, min is 2
`[2,1,3]`, min is 1
`[4,6,1]`, min is 1
`[6,1,3]`, min is 1

所以这个输入的最大值是 2。

有没有什么好方法可以高效运行?

【问题讨论】:

  • 这似乎只依赖于 j-i,而不是独立于 i 和 j。
  • 当 k=0 时,序列从 a_0 开始,但您的索引从 1 开始。
  • k=0 按照惯例意味着a 中的任何元素都不会出现在所选序列中。 :)
  • 这看起来很有趣,但我不明白这个问题。您能否(半)正式定义确切预期的输入和输出是什么?请提供一个示例,其中每个数组包含不同的数字。 (首先,我什至不明白a_ka_l 是什么,如果k=0,那么我们不包括a_0;然后,我也很困惑是否给定一次一对(i,j),或者我们应该处理所有(i,j)s 以及如何作为解决方案。)

标签: algorithm


【解决方案1】:

似乎可以让蛮力方法运行得相当快。

如果您将每个序列预处理成平衡树,其中每个节点都使用该子树的最小值进行扩充,那么您可以通过在适当的位置拆分树在 O(log n) 时间内找到该序列的任何子范围的最小值点。例如,请参阅this paper 了解更多信息。请注意,此预处理需要 O(n) 时间。

我们将范围 (i,j) 称为 窗口。这个问题的复杂程度不取决于具体的(i,j),而是取决于窗口的大小(即j-i+1)。对于 m (=j-i+1) 的窗口大小,有 n-m+1 个该大小的窗口。对于每个窗口,您可以在 m+1 个位置“剪切”窗口,以便元素的某些前缀来自序列a,而后缀来自序列b。您为每次切割支付 O(log n) (如我上面提到的那样拆分二叉树)。这是 O((n-m+1) * (m+1) * log(n)) 的总成本。

可能有一种更快的方法来做到这一点,通过重复使用拆分,或者通过注意附近的窗口共享很多元素。但无论如何,我认为我上面提到的二叉树拆分技巧可能会有所帮助!

【讨论】:

  • 这个O((n-m+1) * (m+1) * log(n)) 不够快。需要更快的,比如O(n log(n))
猜你喜欢
  • 2021-09-27
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-08
  • 2018-07-27
  • 1970-01-01
相关资源
最近更新 更多