给定一个矩阵,都是整数,求出其中的最大子矩阵。
可以将问题转换为求一维数组的最大子序列和的问题。具体见https://blog.youkuaiyun.com/fkyyly/article/details/83088247
/**
* 其实思想是控制新的子矩阵开始,按列相加变成一维数组,然后再求一维数组最大子序列的和,
* 最后在多个最大子序列的和中返回最大的那个
* 然后对如上获取的不同子矩阵分别按列相加生成很多的一维数组
* 然后对每个数组分别求最大子数组的和(因为是求最大子数组的和,所以只需要控制开始的行,不需要控制结束的行也不需要控制开始和结束的列)
* 因为求最大子数组的和可以是中间几个元素的和
* 然后从所有子数组对应的最大子数组的和中选出最大的值
*
* 个人认为如果是限制行的开始,那么就按列相加,然后对一维数组求最大子数组的和
* 如果是限制列的开始,那么就按行相加,然后对一维数组求最大子数组的和
*/
public class MaxSumofMatrix {
public static void main(String[] args) {
//最大子矩阵的累加和
int matrix[][]={{-1,-1,-1},{1,2,2},{8,-7,-1},{-1,100,-1}};
maxMatrixSum(matrix);
}
public static void maxMatrixSum(int matrix[][])
{
if(matrix==null||matrix.length==0)
return;
int max=0;
int col=matrix[0].length,row=matrix.length;
for(int i=0;i<col;i++)
{
int arr[]=new int[col];//存储对应列的和,按列相加
//表示子矩阵从i行开始
for(int j=i;j<row;j++)
{
//下面的循环结合上面的循环就是按列相加
//所以有多少列,arr就有多少个数
for(int k=0;k<col;k++)
{
arr[k]+=matrix[j][k];
// 如果子矩阵是从0开始的话也就是j=i=0,arr[0]=matrix[0][0]+matrix[1][0]+matrix[2][0]+matrix[3][0]+...(所有行的第0个元素)
// 如果子矩阵是从1开始的话也就是j=i=1,arr[0]=matrix[1][0]+matrix[2][0]+matrix[3][0]+...(去除第0行的第0个元素)
// 如果子矩阵是从1开始的话也就是j=i=10,arr[0]=matrix[10][0](去除前9行的第0个元素)
// 比较上面三个表达式,行数在减少
// 将每子行的值进行相加然后利用子数组的最大和就可以求出子矩阵的最大和
}
max=Math.max(maxArrSum(arr), max);
//求出数组的子数组和最大值
}
}
System.out.println(max);
}
public static int maxArrSum(int arr[])
{
int max=0,sum=0;
for(int i=0;i<arr.length;i++)
{
if(sum<=0)
{
sum=arr[i];
}
else {
sum+=arr[i];
}
max=Math.max(sum, max);
}
return max;
}
}