【发布时间】:2020-09-24 08:25:48
【问题描述】:
我在 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)?请注意,Kadane 的算法在 k=n 时运行在O(n) 时间。
【问题讨论】:
-
如果将要跟踪的数组的大小限制为 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 .