考研机试 63.最大子矩阵
时间:2021/03/08
一.题目描述
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。 比如,如下4 * 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15。
输入描述
输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。 再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,
整数之间由空白字符分隔(空格或者空行)。 已知矩阵中整数的范围都在[-127, 127]。
输出描述
测试数据可能有多组,对于每组测试数据,输出最大子矩阵的大小。
题目链接
https://www.nowcoder.com/practice/a5a0b05f0505406ca837a3a76a5419b3?
tpId=40&tqId=21394&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking&tab=answerKey
二.算法
题解
首先计算total数组,total数组为这一列的部分和,然后计算result数组,result数组为这一列的所有可能的子矩阵和(纵向),然后通过computeMax方法求横向的最大子矩阵和,这样便能求出整个矩阵的最大子矩阵和。最好手写把程序跑一遍,这样便能了解里面的原理了。
代码
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); while(in.hasNext()){ //读取输入 int n = in.nextInt(); int[][] num = new int[n][n]; for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ num[i][j] = in.nextInt(); } } //计算最大矩阵 int max = Integer.MIN_VALUE; int[][] total = new int[n][n]; int[] result = new int[n]; for(int i = 0; i < n; i++){ total[0][i] = num[0][i]; } for(int i = 1; i < n; i++){ for(int j = 0; j < n; j++){ total[i][j] = total[i - 1][j] + num[i][j]; } } for(int i = 0; i < n; i++){ for(int j = i; j < n; j++){ for(int k = 0; k < n; k++){ if(i == 0){ result[k] = total[j][k]; }else{ result[k] = total[j][k] - total[i - 1][k]; } } max = Math.max(max, computeMax(result)); } } System.out.println(max); } } //计算当前的最大子矩阵 public static int computeMax(int[] result){ int n = result.length; int[] temp = new int[n]; temp[0] = result[0]; int max = result[0]; for(int i = 1; i < n; i++){ temp[i] = (temp[i - 1] > 0) ? (temp[i - 1] + result[i]) : result[i]; max = Math.max(max, temp[i]); } return max; } }
努力,向上,自律