子数组最大累加和
分为两种方法
思路: 递推法:其实就是用了一次遍历所有的方式,遍历的时候,用了两个模块的方式去判断。
依次相加,如果>=0的就相加,如果<0就直接更新掉
if (sumJ >=0) {//左子表的最大和正,继续向后累加
sumJ += arr[j];
}else{
sumJ = arr[j];
}
如果有大于max的就更新
if (sumJ > max){
max = sumJ;
}
具体思路:
- 先将
sumj = arr[0] ,max = sumj
- 遍历arr{2,3,1,-7,6,-4,2,12,-9,5}
for (int j = 1; j< arr.length; j++)
- 当j为1的时候,此时
sumJ(2) >=0
,所以sumJ += arr[j](3);
则sumj=5
- 再判断
if (sumJ > max)
max = sumJ(5); - 当j为2的时候,此时
sumJ(5) >=0
,所以sumJ += arr[j] (1)
则sumj=6 - 再判断
if (sumJ > max)
max = sumJ(6); - 当j为3的时候,此时
sumJ(6)>0
,所以sumJ+=arr[j] (-7)
则sumj=-1 - 再判断是否
if (sumJ > max)
sumj<max - 当j为4的时候,此时
sumj(-1)<0
,所以丢弃前面的部分,直接sumJ = arr[j];
此时sumj = 6 - 。。。。。。。
public class 子数组最大累加和 {
static void findByForce(int[] arr){
int maxSum = arr[0];
for(int j = 0; j < arr.length; j++){
int sum = arr[j]; //某个元素为子数组的第一个元素
int maxOfJ = sum;
for (int i=j+1;i<arr.length;i++){
sum+=arr[i];//累加后续元素
if (sum > maxOfJ){
maxOfJ = sum;
}
}
if (maxOfJ>maxSum){
maxSum = maxOfJ;
}
}
System.out.println(maxSum);
}
//递推法 0(n)
static int findByDp(int[] arr){
int sumJ = arr[0]; //前J个元素的最大贡献
int max = sumJ;
int left = 0,right = 0;
for (int j = 1; j< arr.length; j++){
if (sumJ >=0) {//左子表的最大和正,继续向后累加
sumJ += arr[j];
}else{
sumJ = arr[j];
left=j;//丢弃前部分和的同时,更新left
}
if (sumJ > max){
max = sumJ;
right = j;//更新max的同时更新right
}
}
// System.out.println(max=",left="+left+",right:"+right")
return max;
}
public static void main(String[] args){
int[] arr = {2,3,1,-7,6,-4,2,12,-9,5};
long now = new Date().getTime();
findByForce(arr);
long next1 = new Date().getTime();
System.out.println("暴力法,时间消耗"+(next1-now));
findByDp(arr);
long next2 = new Date().getTime();
System.out.println("递推法:"+(next2-next1));
}
}