子数组最大累加和
给定一个数组arr,返回子数组的最大累加和
例:arr=[1,-2,3,5,-2,6,-1];所有的子数组中[3,5,-2,6]可以累加出最大的和12,所以返回12
static void findByForce(int[] arr){
int manSum=arr[0];
for(int i=0;i<arr.length;i++){
int sum=arr[j];//某个元素为子数组的第一个元素
int maxOfJ=sum;
for(int i=j;i<arr.length;i++){
sum+=arr[i];//累加后续元素
if(sum>maxOfJ){
maxOfJ=sum;//某个元素后续最大累加
}
}
if(maxOfJ>maxSum){
maxSum=maxOfJ;// 总的最大值
}
}
System.out.println(maxSum);
}
//递推法 o(n)
static int findByDp(int[] arr){
int sumJ=arr[0];///前J个元素的最大贡献
int max=sumJ;
int left=0;right=0;//***若是求最大值之间的下标
int temp;//记录最大值的letf
for(int j=1;j<arr.length;j++){
if(sumJ>=0){//左子表的最大和为正,继续向后累加
sumJ+=arr[j];//若是大于0,则可以要前面的一段
}else{//若是小于0,则从当前位置重新开始
sumJ=arr[j];
// left=j;//重新开始时,更新left
//**上面那行是错的,他最终只会停在最后一次sumJ小于0的位置
temp=j;
}
if(sumJ>max){//最大值
left=temp;//*如此,只有最大值得到更新,才能更新letf
max=sumJ;
// 每次求得最大值,更新最大值时,同时更新right
right=j;
}
}
return max;
}
子矩阵最大累加和
给定一个矩阵matrix,其中的值有正、有负、有0、返回子矩阵的最大累加和
例如,matrix为:
-1 -1 -1
-1 2 2
-1 -1 -1
其中最大累加和的子矩阵为
2 2
所以返回4
从第一行开始,作为起始行,先求第一行,找最大子数组和,再将下一行于上一行累加到一起,找最大子数组和
然后变更起始行,继续之前的循环
private static int maxSum(int[][] matrix){
int beginRow=0;
final int M=matrix.length;
final int N=matrix[0].length;
int[] sums=new int[N];//按列求和
int max=0;//历史最大的子矩阵和
while(beginRow<M){//起始行
for(int i=beginRow;i<M;i++){//从起始行到最后一行
//按列累加
for(int j=0;j<N;j++){
sums[j]+=matrix[i][j];
}
//累加完成
int t=findByDp(sums);//求出sums的最大和子数组
if(t>max)
max=t;
}
//另起一行作为起始行,把sums清零
Arrays.fill(sums,0);//将sums的每个元素都设定为0
beginRoww++;//以下一行作为起始行
}
return max;
}
public static int findByDp(int[] arr){
if(arr.length==0)return 0;
int sumJ=arr[0];///前J个元素的最大贡献
int max=sumJ;
int left=0;right=0;//***若是求最大值之间的下标
int temp;//记录最大值的letf
for(int j=1;j<arr.length;j++){
if(sumJ>=0){//左子表的最大和为正,继续向后累加
sumJ+=arr[j];//若是大于0,则可以要前面的一段
}else{//若是小于0,则从当前位置重新开始
sumJ=arr[j];
// left=j;//重新开始时,更新left
//**上面那行是错的,他最终只会停在最后一次sumJ小于0的位置
temp=j;
}
if(sumJ>max){//最大值
left=temp;//*如此,只有最大值得到更新,才能更新letf
max=sumJ;
// 每次求得最大值,更新最大值时,同时更新right
right=j;
}
}
return max;
}