请注意,我从这个答案中得出了我的解释。它演示了如何将 Kadane 的算法视为具有重叠子问题的 DP 算法。
识别子问题和递归关系
想象一下,我们有一个数组a
,我们想从中获取最大子数组。为了确定以索引结束的最大子数组,i
以下递归关系成立:
max_subarray_to(i) = max(max_subarray_to(i - 1) + a[i], a[i])
为了获得a
我们需要计算max_subarray_to()
每个索引i
的最大子数组,a
然后从中获取max()
:
max_subarray = max( for i=1 to n max_subarray_to(i) )
例子
现在,假设我们有一个数组[10, -12, 11, 9]
,我们想要从中获取最大子数组。这将是运行 Kadane 算法所需的工作:
result = max(max_subarray_to(0), max_subarray_to(1), max_subarray_to(2), max_subarray_to(3))
max_subarray_to(0) = 10 # base case
max_subarray_to(1) = max(max_subarray_to(0) + (-12), -12)
max_subarray_to(2) = max(max_subarray_to(1) + 11, 11)
max_subarray_to(3) = max(max_subarray_to(2) + 9, 49)
如您所见,除了最后一个索引之外max_subarray_to()
,每个索引都被评估了两次,因此表明 Kadane 的算法确实有重叠的子问题i
3
。
Kadane 的算法通常使用自下而上的 DP 方法来实现,以利用重叠的子问题并且只计算每个子问题一次,因此将其转换为 O(n)。