面试题 17.24. 最大子矩阵

LeetCode原题:面试题 17.24. 最大子矩阵
题目描述:
*给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。
返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。
注意:本题相对书上原题稍作改动
示例:
输入:
[
[-1,0],
[0,-1]
]
输出:[0,1,0,1]
解释:输入中标粗的元素即为输出所表示的矩阵

说明:
1 <= matrix.length, matrix[0].length <= 200*
题目思路:
1)做这道题目的前提是弄懂“最大子序和”这道题,本题的思想是把不同行同一列的元素求和,用一维数组对应存储每列的和,再对这个一维数组运用“最大子序和”的求解方法。(数据量最大200,暗示可以开三层for)
2)然后需要记录选中左上角和右下角元素的坐标
2.1)当pre不大于0时,证明左上角坐标更新,此时需要把左上角坐标用变量存储起来。
2.2)当记录最大值的maxSum更新时,证明此时右下角坐标更新,当前和最大的子矩阵已经找出,把当前的横纵坐标记录下来。
3)最后返回记录下标的数组。

public class MaximalSubmatrix {
    public static void main(String[] args) {
        int[][] arr = new int[][]{{-1,2,3},{-1,-1,-2},{-2,3,1}};
        int[] RES = new int[3];
        RES = getMaxMatrix(arr);
        for(int res : RES){
            System.out.print(res + ",");
        }
    }
    public static int[] getMaxMatrix(int[][] matrix) {
        int rowLength = matrix.length;//二维数组行数
        int colLength = matrix[0].length;//二维数组列数
        int sum[] = new int[colLength];//用来记录同一列不同行元素相加的值
        int[] res = new int[]{-1,-1,200,200};//记录返回坐标的数组
        int maxSum = Integer.MIN_VALUE;//声明变量用来存储最大值,初始值设置为int最小值
        int subscriptR = 0 , subscriptC = 0;//用来记录左上角选中元素的坐标

        for(int i = 0 ; i < rowLength ; ++i){
            Arrays.fill(sum , 0);//每次i+1,意味着要重新开始降维打击了,因此要把sum全部归0
            for(int j = i ; j < rowLength ; ++j){
                int pre = 0;//pre是最大连续自序和的做法
                for(int k = 0 ; k < colLength ; ++k){
                    sum[k] += matrix[j][k];//降为打击,把遍历过的行的同一列内容分别加到一个一维数组中
                    if(pre > 0){//如果pre大于0,证明对后面值变大有帮助,此时直接与后面元素相加,并且不需要更新左上角值
                        pre += sum[k];
                    }else{//如果pre不大于0,证明这个pre,对后面值变大没有帮助,我们直接用后面的值覆盖pre,并且更新左上角值坐标
                        pre = sum[k];
                        subscriptR = i;
                        subscriptC = k;
                    }
                    if(maxSum <= pre){//如果pre大于此时我们的maxSum,证明子矩阵和最大值需要更新,
                        maxSum = pre;//我们更新maxSum并且记录此时子矩阵最大和对应左上角和右下角坐标
                        res[0] = subscriptR;//左上角坐标在pre小与0时已经用变量记录下来了
                        res[1] = subscriptC;
                        res[2] = j;//右下角坐标就是我们当前遍历到的元素的坐标,第j行,第k列的那个元素
                        res[3] = k;
                    }
                }
            }
        }
        System.out.println(maxSum);
        return res;//返回记录下标的数组即可
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值