1.题目
2.解法 1(遍历)
刚开始的思路是:
-
假设有这样一个数组,为了防止第一个值为负数,所以 max = add = array[0]
{1,-2,3,10,-4,7,2,-5} -
每进行一次累加,都需要判断add是否大于max值,若大的话直接替代
这一步是包括了数组元素值为正负两种情况:
- if(array[i] < 0){ if (add > max) max = add}
如果此时该数组小于0,需要保存最大值,也需要add大于max值。
-if(array[i] < 0) 如果为正,也需要判断
所以就不需要判断正负了 -
如果add值加的过程中小于数组元素值,那么就不需要加了,直接从该元素值开始。
例如 1+ (-2) + 3 = 2 2 < 3,那么就从3开始。
代码为:
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
if (array == null || array.length == 0) {
return 0;}
int max = array[0];
int add = array[0];
for(int i = 1; i < array.length; i++){
add += array[i];
if(array[i] > add){
add = array[i];
}
if(add > max){
max = add;
}
}
return max;
}
}
以上方法不管元素是正是负都会加,除非有一个if(array[i] > add)
- 假设有 -1 -2 -3 -4 -5,第一个元素就是最大值,但是程序还是往后一直加
所以说需要进行判断add - 如果add <= 0 了,如果后一个元素为负值,那么结果更小了,如果后一个元素为正值,那么也会使结果更小, 那就直接从此时的array[i]重新开始
假设add > 0 那么就加上此时的array[i]
此时代码为
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
if (array == null || array.length == 0) {
return 0;}
int max = array[0];
int add = array[0];
for(int i = 1; i < array.length; i++){
if(add <= 0){
add = array[i];
}else{
add += array[i];
}
if(add > max){
max = add;
}
}
return max;
}
}
解法2:动态规划
以每个数组元素结尾都是一个子数组,所以总能共有n个子数组
下标为0<= index <n
如果f(i-1)<= 0 ,那么加上下一个元素只会使得结果更小,所以从下一个元素直接开始,否则f(i-1) > 0,直接加下一个元素
这个方法和上面的思路一样,都是从add为正为负考虑问题
public class Solution {
public static int FindGreatestSumOfSubArray(int[] array) {
int len = array.length;
if (array == null || len == 0) {
return 0;}
int[] adds = new int[len];
// 1.如果只有一个元素,最大值为
adds[0] = array[0];
int max = array[0];
for(int i = 1; i < len; i++){
// 如果累加的值为负数,那么就没有必要再加了
if(adds[i-1] <= 0){
adds[i] = array[i];
}else{
adds[i] = adds[i-1] + array[i];
}
if(max < adds[i]){
max = adds[i];
}
}
return max;
}
}
时间复杂度都为O(n)