题目描述
给定一个矩阵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
思路
参考自《程序员代码面试指南》。
第一层循环:枚举开始的行数i,范围从0到n-1。
第二层循环:枚举结束的行数j,范围从i到n-1。
第三层循环:枚举从开始行到结束行的所有可能累加和。将同一列的j-i+1个元素合成一个元素,就可以参考子数组的最大累计和问题的求解思路:设置变量为cur,从左向右遍历的过程中,每次令cur+=当前元素,根据cur更新当前的max值,然后判断cur是否小于0,如果不小于0,维持原样,如果小于零,更新cur为0。
注意将i到j同一列的j-i+1个元素合成一个元素的过程可以根据上一次的结果累加进行,时间复杂度为O(1)。
代码实现
import java.util.Scanner;
public class Main{
public static void main(String []args){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int [][]arr = new int [n][m];
for(int i = 0 ; i<n ; i++){
for(int j = 0 ; j<m ; j++){
arr[i][j] = scanner.nextInt();
}
}
int cur = 0;
int max = Integer.MIN_VALUE;
for(int i = 0 ; i<n ; i++){
int []s = new int[m];
for(int j = i ; j<n ; j++){
cur = 0 ;
for(int k = 0 ; k<m ; k++){
s[k] += arr[j][k];
cur += s[k];
max = Math.max(max, cur);
cur = (cur < 0)? 0:cur;
}
}
}
System.out.println(max);
}
}