连续子数组的最大和 and 无序数组最大前后差
设sum[i]为以第i个元素结尾且和最大的连续子数组。假设对于元素i,所有以它前面的元素结尾的子数组的长度都已经求得,那么以第i个元素结尾且和最大的连续子数组实际上,要么是以第i-1个元素结尾且和最大的连续子数组加上这个元素,要么是只包含第i个元素,即sum[i] = max(sum[i-1] + a[i], a[i])。可以通过判断sum[i-1] + a[i]是否大于a[i]来做选择,而这实际上等价于判断sum[i-1]是否大于0。由于每次运算只需要前一次的结果,因此并不需要像普通的动态规划那样保留之前所有的计算结果,只需要保留上一次的即可,因此算法的时间和空间复杂度都很小。最长公共子序列每次要用到前面的那个结果不确定,所以需要一个完整的一维数组记录前面的结果。
本题的最优解是子问题中的一个,而不是子问题的最后一个,需要和最长公共子序列相同。
public int FindGreatestSumOfSubArray(int[] array) {
int sum = 0,result = Integer.MIN_VALUE;
for(int i = 0;i<array.length;i++){
//精简版
//result = Math.max(result, sum = sum > 0 ? sum + array[i] : array[i]);
sum = sum > 0 ? sum + array[i] : array[i];//核心代码和模式
if (result < sum){ //判断所有和中那个是最大,每次比较保留最大的。
result = sum;
}
}
return result;
}
无序数组最大前后差
public int FindGreatestdiff(int[] array) {
int diff = 0,result = Integer.MIN_VALUE;
for(int i = 0;i<array.length;i++){
// 精简版
//result = Math.max(result, diff = diff > 0 ? diff + array[i+1] - array[i] : array[i+1] - array[i]);
diff= diff < 0 ? array[i+1] - array[i] : diff + array[i+1] - array[i];//核心代码和模式
if (result < diff){ //判断所有和中那个是最大,每次比较保留最大的。
result = diff;
}
}
return result;
}
解法2
从左往右求下标0到 k - 1 的最小值MIN 从右往左求 下标k到n -1 的最大值MAX,对于每个k都有一个MAX - MIN的值,最后求这个值的最大值即可。
例如数组:4 5 2 6 3 1
K:1 2 3 4 5
MIN: 4 4 2 2 2
MAX:6 6 6 3 1
MAX - MIN,最大的值为6 - 2 = 4, 即为结果