Loading

考研机试 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;
    }
}

 

posted @ 2021-03-08 22:37    阅读(93)  评论(0编辑  收藏  举报