如果此问题似乎是重复,请指出。
问题是:
给定一个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)。 (也许我在某个地方弄错了数字!)
寻找你们的指示!欢迎使用单词和伪代码!
答案 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)。