zoukankan      html  css  js  c++  java
  • 算法——求矩阵中和最大的子矩阵

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

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

    解题思路:

    • 首先为了在O(1)的时间内获取两个点之间的矩阵和,就需要求每个点的前缀和,然后通过前缀和的是运算,快速获取两个点构成的矩阵的和。
    • 然后是遍历整个数组,但是如果依次枚举每两个点的话,时间复杂度是n的四次方的,会超时。所以,这里需要利用动态规划的思想。如果让一个维度不变,就可以把问题变为一维数组求和最小的连续字串问题,当前缀小于零,那就只会给后面添累赘,所以直接就去掉。
    class Solution {
        public int[] getMaxMatrix(int[][] matrix) {
            int n = matrix.length;
            if(n == 0) return new int[0];
            int m = matrix[0].length;
    
            int[][] f = new int[n + 1][m + 1];
            int[][] s = new int[n + 1][m + 1];
    
    		// 求二维的前缀和
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= m; j++) {
                    s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + matrix[i - 1][j - 1];
                }
            }
    
            int[] res = new int[4];
            int sum = matrix[0][0];
    
    		// 先枚举一个维度,再枚举另一个维度,这样就将为一维数组求和最大的连续子串问题。
            for(int i = 1; i < n + 1; i++) {
                for(int j = 0; j < i; j++) {
                    int start = 0;
                    for(int k = 1; k < m + 1; k ++) {
                        int cur = s[i][k] - s[j][k] - s[i][start] + s[j][start];
                        if(cur > sum) {
                            sum = cur;
                            res = new int[]{j, start, i - 1, k - 1};
                        }
    					// 如果前面的和小于零,只会拖累后面,索性直接去掉前面的
                        if(cur < 0) start = k;
                    }
                }
            }
    
            return res;
        }
    }
    
  • 相关阅读:
    UniConnector平台
    UniConnector平台
    UniChat 社交IM 集成环信
    移动办公OA App 工作流审批
    netcore 部署Docker
    .net core 腾讯短信发送
    Linux error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
    Linux nginx 自启动
    Linux 配置、问题
    Swagger自定义默认首页
  • 原文地址:https://www.cnblogs.com/lippon/p/14117614.html
Copyright © 2011-2022 走看看