Arrays 具有长度约束的最大子阵
我在CS.SE问过这个问题,但没有得到回应 我最近面临以下面试问题: 给定数组A和整数k,查找具有 最大和,加上约束,该子数组的长度最多为k 因此,如果Arrays 具有长度约束的最大子阵,arrays,algorithm,max,Arrays,Algorithm,Max,我在CS.SE问过这个问题,但没有得到回应 我最近面临以下面试问题: 给定数组A和整数k,查找具有 最大和,加上约束,该子数组的长度最多为k 因此,如果A=[8,-1,-1,4,-2,-3,5,6,-3]那么我们得到了k的不同值的以下答案: +---+------------------------------+ | k | subarray | +---+------------------------------+ | 1 | [8]
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(nlgk)
;是否有办法将此改进为O(n)
?请注意,当k=n时,Kadane的算法在O(n)
时间内运行。您可以在O(n)时间内运行。这是怎么做的
- 让我们定义部分和的数组
B
B[x]=sum(i in(0,x+1),a[i])
- 现在问题变成了查找索引q和w,这样
如果将跟踪的数组大小限制为k,Kadane的算法会失败什么?@G.Bach:当k=7时,尝试对问题中的数组执行此操作。当您到达5
时,在那里结束的最大数组是[8,-1,-1,4,-2,-3,5]
。但是,当您移动到6
时,需要删除8
;这会导致连锁反应,使-1,-1,4,-2,-3
,因为长度最多为7的最大子数组,在6
处结束,是[5,6]
。换句话说,您需要在遍历数组时跟踪要“丢弃”的元素,而一个简单的实现会导致与n*k成比例的时间。您确定吗?你会有两个指针,一个左一个右,每个指针都会遍历数组一次,不是吗?@G.Bach:我非常有兴趣了解如何工作的细节。我不明白如何通过修改Kadane的算法来做到这一点:有k个子数组可以停在任何给定的元素上(长度为1,2,…,k),遍历它们都需要n*k。我相信这是正确的,但需要指出的是,您保持不变,即deque中列出的位置对应于B[]的非减损值——这使您能够确信deque.front()
始终是最小生产位置,不必搜索deque中的每个元素来寻找最小的元素。这太棒了!这与我的做法非常相似:我实际上是在修正w并搜索最优q。为此,我维护了一个堆,以便快速获得最大值B[q]。这个答案不仅正确,而且改进了我原来的解决方案。你确定吗?如何保持递增B
的不变性?以op为例,您将拥有B==[0,8,7,6,10…]
。这听起来不太对劲。我得到了它。天啊,它太聪明了。对于那些想了解更多关于这种deque技术的人来说,它被称为Min/Max队列,并在这些问题中找到它最基本的用例。
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();