具有长度约束的最大子阵列

时间:2015-09-11 06:52:38

标签: arrays algorithm max

我在CS.SE问过这个问题,但没有回复。

我最近面临以下面试问题:

  

给定一个数组A和一个整数k,找到一个连续的子数组   最大总和,加上约束,此子阵列的长度最多为k。

因此,如果A=[8, -1, -1, 4, -2, -3, 5, 6, -3],我们会针对k的不同值获得以下答案:

+---+------------------------------+
| k |           subarray           |
+---+------------------------------+
| 1 | [8]                          |
| 7 | [5,6]                        |
| 8 | [8, -1, -1, 4, -2, -3, 5, 6] |
+---+------------------------------+

如果n是数组A的长度,那么使用修改后的优先级队列,我能够及时回答这个问题O(n lgk);有没有办法将其改进为O(n)?请注意,当k = n时,Kadane算法在O(n)时运行。

1 个答案:

答案 0 :(得分:4)

你可以在O(n)中完成。这是怎么回事。

  • 让我们定义部分和B
  • 的数组B[x] = sum(i in (0, x+1), a[i])
  • 现在问题变为找到索引q和w,使得w<=qq-w <=kB[q] - B[w]是可能的最大值。

为此,我们将通过数组B找到q。由于B[q]已修复,因此当B[w]为最小值时,我们会最大化表达式。我们保持双端队列以快速找到w。双端队列将保留潜在最小值的位置。要更新它:取出第一个元素,因为它超出了你想要的k间隔,从后面提取所有值,这些值大于当前位置的值,最后在后面插入当前位置。

应该是这样的

for (q in len(b))
  // The minimum is too far behind
  if !deque.empty() && q - deque.front() > k: deque.pop_front() 
  // Remove the less optimal positions from the queue.
  while (!deque.empty() && b[deque.back()] > b[q]) deque.pop_back() 
  deque.push_back(q)

  if (b[q] - b[deque.front()] > best_so_far) UpdateBestSoFar();

它可能看起来像O(N ^ 2),因为内部虽然但不是。每个元素一次插入双端队列并提取一次。所以迭代的总数是O(N)。

相关问题