在数组中以多于O(N * M)时间的多个间隔查找min元素

时间:2014-09-12 18:12:30

标签: arrays algorithm time-complexity

我有三个数组:A,B,C。B和C的对应索引给出了在A中搜索的间隔。 例如:B [0] = 1,C [0] = 7所以从A(含)中的索引1到7进行搜索。

我需要在A中找到每个间隔的min并将其作为int数组返回。我认为我提出的解决方案是在O(N * M)中运行,其中N是数组A的大小,M是B和C的大小。我循环遍历A中的每个区间并找到min。

有谁知道如何改进O(N + M)的解决方案?

注意:网站上说问题可以在O(N + M)时间(codility.com)解决。我不只是在猜测。它也来自前缀总和的一个部分,但我还没有能够找到一种方法来使用它们比O(N * M)解决方案更好。 A没有排序。

3 个答案:

答案 0 :(得分:3)

这是range minimum query问题的一个非常薄的层。对于最佳方案,使用O(N)预处理,可以在时间O(1)中回答查询,但实现相当复杂。如果您想尝试,TopCoder会托管nice tutorial by danielp

答案 1 :(得分:2)

大字母表的解决方案1 ​​

您可以为i和k的每个值预先计算A [i:i + 2 ** k]的最小值,直到ceil(log(N))。

这需要O(N log(N))预处理和O(N log(N))存储。

然后可以在O(1)中回答每个查询的总复杂度为O(Nlog(N)+ M)。

例如,要找到A [2:13]的最小值,您可以找到A [2:2 + 2 ** 3]和A [5:5 + 2 ** 3]的预计算结果的最小值

小字母表的解决方案2

如果A中不同元素的数量很小并且是固定的,例如10,然后你可以使用前缀和在O(N + M)中执行此操作。

简单地计算每个不同元素e P [e] [i]的前缀和,其计算索引< = i的e的出现次数。然后,对于每个查询,您可以通过对每个元素类型的简单减法来确定特定元素是否存在于该范围内。

这需要O(KN)预处理和O(KM)查询时间,其中K是A中不同元素的数量。

对于固定的K,这变为O(N + M)。

答案 2 :(得分:0)

四年后,没有人回答这个问题。

我用一个四列的矩阵(每个核苷酸的类型为1)对this question进行求解,每次该核苷酸出现在序列上就加一个。

这样,您就可以计算出每种核苷酸类型是否出现在该间隔上。

请记住,O(4 * n)变为O(n),并且O(m + n)与O(m + 4n)相同。