采访问题: - 给定一个数组和一个整数k,找到每个大小为k的连续子数组的最大值。
Sample Input :
1 2 3 1 4 5 2 3 6
3 [ value of k ]
Sample Output :
3
3
4
5
5
5
6
我无法想到比蛮力更好的东西。当数组按降序排序时,最坏的情况是O(nk)。
答案 0 :(得分:2)
只需遍历数组并在self-balancing binary tree中保留k
个最后元素。
向此树添加元素,删除元素并查找当前最高成本O(logk)
。
大多数语言为此类树提供标准实现。在STL,IIRC,它是MultiSet
。在Java中,你使用TreeMap
(map,因为你需要保持计数,每个元素出现多少次,而Java不提供Multi-collections)。
伪代码
for (int i = 0; i < n; ++i) {
tree.add(a[i]);
if (tree.size() > k) {
tree.remove(a[i - k]);
}
if (tree.size() == k) {
print(tree.max());
}
}
答案 1 :(得分:2)
实际上你可以在O(n)时间内用O(n)空间做到这一点。
将数组拆分为每个数组。
[a1 a2 ... ak] [a(k+1) ... a2k] ...
对于每个块,再保留两个块,即左侧块和右侧块。
左侧块的第i个元素将是左侧的i个元素的最大值。 右侧块的第i个元素将是右侧的i个元素的最大值。
每个k块都有两个这样的块。
现在,如果您想要找到范围a[i... i+k]
中的最大值,请说这些元素跨越上述两个k块。
[j-k+1 ... i i+1 ... j] [j+1 ... i+k ... j+k]
您需要做的就是找到第一个块i to j
的RightMax和第二个块的j+1 to i+k
的最大值。
答案 2 :(得分:1)
希望这是您正在寻找的解决方案:
def MaxContigousSum(lst, n):
m = [0]
if lst[0] > 0:
m[0] = lst[0]
maxsum = m[0]
for i in range(1, n):
if m[i - 1] + lst[i] > 0:
m.append(m[i - 1] + lst[i])
else:
m.append(0)
if m[i] > maxsum:
maxsum = m[i]
return maxsum
lst = [-2, 11, -4, 13, -5, 2, 1, -3, 4, -2, -1, -6, -9]
print MaxContigousSum(lst, len(lst))
**Output**
20 for [11, -4, 13]