请注意,我从
这个答案中提取了我的解释。它展示了Kadane算法可以被视为具有重叠子问题的DP算法。
确定子问题和递推关系
假设我们有一个数组
a
,我们希望从中获取最大子数组。要确定以索引
i 结尾的最大子数组,以下递归关系成立:
max_subarray_to(i) = max(max_subarray_to(i - 1) + a[i], a[i])
为了获得数组
a
的最大子数组,我们需要计算
a
中每个索引
i
的
max_subarray_to()
,然后从中取出最大值
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)
正如您所看到的,除了最后一个索引3之外,每个i对应的
max_subarray_to()
都被评估两次,因此表明Kadane算法确实存在重叠子问题。通常使用自底向上的DP方法来实现Kadane算法,以利用重叠子问题并只计算每个子问题一次,从而将其转换为O(n)。