k个连续元素的局部mins的全局最大值

时间:2014-02-23 05:42:11

标签: algorithm

如果此问题似乎是重复,请指出。

问题是:

  

给定一个n个元素的数组和一个整数k <= n,找到{0 ... nk}}中i的{min {a_i + 1 ... a_i + k}的最大值,即找到k个连续数的最大分数。

     

例如,让序列a = {10,21,11,13,16,15,12,9}和k = 3。   块{13,16,15}的最大值为13。

希望问题很清楚!

直接有一个简单的“蛮力”使它成为O(nk)。我想知道我们是否可以在O(nlogn)中使用“分而治之”,甚至在O(n)中使用“动态编程”。

在我看来,如果我尝试“分而治之”,我必须处理一组跨越中间边界的区块。然而,在这种情况下计算出最大值似乎需要O(k2),再次使整个复发O(nk)。 (也许我在某个地方弄错了数字!)

寻找你们的指示!欢迎使用单词和伪代码!

2 个答案:

答案 0 :(得分:1)

你可以在O(n log k)时间内完成;我会给你一个提示。

假设在某些数据结构中有 i + 1 ,..., i + k 元素,其中对数时间插入和常数时间min操作(如最小堆)。你可以使用它来获得相同的数据结构,但元素a i + 2 ,..., i + k + 1  在O(log k)时间?

一旦你有了这个,那么你基本上可以通过k的所有连续组并正常地取最小值。

答案 1 :(得分:1)

这是使用类似动态编程的解决方案解决它的一种方法。我们构造一个数组“ys”,存储不断增加的范围的分钟。它使用的想法是,如果ys当前存储长度为p的范围的分钟,那么如果我们对所有i:ys[i] = min(ys[i], ys[i+p])进行分配,那么我们现在已经获得了长度为2p的分钟。同样,如果我们做ys[i] = min(ys[i], ys[i+p], xs[i+2p]),那么我们得到的长度为2p + 1的范围。通过使用非常类似于求平方的技术,我们最终可以用ys存储长度为k的最小范围。

def mins(xs, k, ys):
    if k == 1: return ys
    mins(xs, k // 2, ys)
    for i in xrange(len(ys)):
        if i + k//2 < len(ys): ys[i] = min(ys[i], ys[i+k//2])
        if k % 2:
            if i+k-1 < len(ys): ys[i] = min(ys[i], xs[i+k-1])
    return ys

def maxmin(xs, k):
    return max(mins(xs, k, xs[:]))

我们递归地调用mins log_2(k)次,否则我们每次调用迭代ys数组一次。因此,算法是O(n log k)。