题目:
1.给定一个数组array,返回子数组的最大累加和。
例如:array=[1,-2,3,5,-2,6,-1],所有的子数组中,[3,5,-2,6]累加出的和最大,为12,所以返回12.
分析:
本题要遍历数组,毫无疑问。但核心在于该如何正确的遍历数组来得到累加和最大的子数组?
解决:从左到右遍历array,用count记录每一步的累加和,若遍历到正数,count增加,若遍历到负数,count减少。当count<0时,说明累加到当前数出现了小于0的结果,则这一部分不能作为产生最大累加和的子数组左边的部分,此时又将count置为0,从下一个开始遍历。
但是:若是count>=0,每一次累加都可能是最大的累加和,因此,在引入一个变量来记录count出现的最大值,将这个变量记为max.
完整代码实现:
public int maxSum(int[] array){
if(array==null||array.length==0){
return 0;
}
int count=0;
int max=Integer.MIN_VALUE; //初始化变量
for(int i=0;i<array.length;i++){
count+=array[i];
max=Math.max(count,max);
count=count<0?0:count; //若count<0,将count置为0,从下一个开始遍历
}
return max;
}
2.给定一个矩阵matrix,其中的值有正,有负,有0,返回子矩阵的最大累加和。
例:
矩阵matrix为:
-90 48 78
64 -40 64
-81 -7 66
其中,最大累加和的子矩阵为:
48 78
-40 64
-7 66
所以返回的累加和为209
例如:matrix为:
-1 -1 -1
-1 2 2
-1 -1 -1
其中,最大累加和的子矩阵为:
2 2
所以返回累加和:4
问题分析:利用上题求子数组的最大累加和问题的解法来处理,可以将每列的元素累加,得到累加数组,然后求这个累加数组的最大累加和,这个最大累加和就是子矩阵中的最大累加和
解答:
矩阵为:
-1 -1 -1
-1 2 2
-1 -1 -1
步骤:
从第一行开始往下查找
(1):考虑只有一行的矩阵:[-1 ,-1,-1],即累加数组就为:[-1 ,-1,-1]
(2):考虑含有两行的矩阵:
-1 -1 -1
-1 2 2
每列相加,得到这个矩阵的累加数组为:[-2,1,1],这个数组的最大累加和为:2
(3):考虑含有三行的矩阵:
-1 -1 -1
-1 2 2
-1 -1 -1
在上一步累加数组[-2,1,1]的基础上,依次在每个位置上加上矩阵最新一行[-1,-1,-1],则这个矩阵的累加数组为:[-3,0,0]
此时:从第一行开始,往下的所有子矩阵已经查找完毕
现从第二行元素开始往下查找:
(1)考虑只有一行的矩阵:[ -1 , 2 , 2],这个数组的最大累加和为4
(2)考虑含有两行的矩阵:
-1 2 2
-1 -1 -1
这个矩阵的累加数组为:[0,1,1],这个数组的最大累加和为:2
此时:从第二行开始,往下的所有子矩阵已经查找完毕
现从第三行元素开始往下查找:
含有一行矩阵:-1 -1 -1
现已都查找完毕,结果就为以上所有累加和中最大的为4
代码实现:
public int maxSum(int[][] array){
if(array==null||array.length==0||array[0].length==0){
return 0;
}
int count=0;
int max=Integer.MIN_VALUE;
int[] sum=null; //初始化累加数组
for(int i=0;i!=array.length;i++){
sum=new int[array[0].length];
for(int j=i;j!=array.length;j++){
count=0;
for(int k=0;k!=sum.length;k++){
sum[k]+=array[j][k]; //列求和
count+=sum[k];
max=Math.max(count,max);
count=count<0?0:count;
}
}
}
return max;
}
解决此问题的关键在于如何想到处理方法,并结合已经解决的求子数组的最大累加和问题。
核心:用求累加数组的最大累加和的方式得到每一步的最大子矩阵的累加和。