求连续子数组和的最大值,是一个很经典的问题,网上有很多文章来介绍这个问题,我们先简要介绍一下这个问题的动态规划解法。
对于一个输入数组a[n],我们用res表示该数组连续子数组和的最大值,用sum[i]表示前i个元素中,包含第i个元素且和最大的连续子数组的和,这样我们可以从头到尾遍历数组,执行以下公式:
sum[i + 1] = max (a[i + 1], sum[i])
res= max (res, sum[i + 1])
对于sum数组,我们在一个时刻只会使用一个值,可以简化为一个数,具体代码如下所示:
int solve(int[] a) {
if (a == null || a.length == 0) {
return -1;
}
int sum = a[0], res = a[0];
for (int i = 1; i < a.length; i++) {
if (sum < 0) {
sum = 0;
}
sum += a[i];
res = Math.max(sum, res);
}
return res;
}
但是,这个问题并不是本文所讨论的重点,我们要讨论的是该问题的两个变种问题。
变种一:求连续子数组和的绝对值的最小值
这个问题乍看一下,不是也能用动态规划的思想来解决吗?解法如下