面试题之最大子矩阵

题目如下:

面试题 17.24. 最大子矩阵

给定一个正整数、负整数和 0 组成的 N × M 矩阵,编写代码找出元素总和最大的子矩阵。

返回一个数组 [r1, c1, r2, c2],其中 r1, c1 分别代表子矩阵左上角的行号和列号,r2, c2 分别代表右下角的行号和列号。若有多个满足条件的子矩阵,返回任意一个均可。

思路如下:

解题思路

本题的子问题为《LeetCode 53.最大子序和》,不同的是本题为二维矩阵,因此需要将二维矩阵“打成”一维,然后套用最大子串和,打的手段是使用preSum前缀和,能够在O(1)的时间复杂度内求得。整体是用3-for三层循环,在最内层循环里使用最大子序和的dp算法,鉴于题目给的输入范围为200以内,所以时间上也能过得去。代码如下:

代码

class Solution {
    public int[] getMaxMatrix(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        int[][] preSum = new int[m][n];
        
        for(int i = 0; i < n; i++) {
            preSum[0][i] = matrix[0][i];
            for(int j = 1; j < m; j++) {
                preSum[j][i] = preSum[j-1][i] + matrix[j][i];
            }
        }

        int[] res = new int[4];
        int max = Integer.MIN_VALUE;
        for(int i = m-1; i >= 0; i--) {
            for(int j = 0; j <= i; j++) {
                int begin = 0;
                int temp = 0;

                //开始最大子序和的dp求解
                int sum = 0, ans = 0;
                for(int k = 0; k < n; k++) {
                    temp = preSum[i][k] - (j>0 ? preSum[j-1][k] : 0);
    
                    if(sum > 0) {
                        sum += temp;
                    }else {
                        sum = temp;
                        begin = k;
                    }

                    if(sum > max) {
                        max = sum;
                        res[0] = j; res[2] = i; res[1] = begin; res[3] = k;
                    }
                }
            }
        }

        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值