lc17.24最大子矩阵

给定包含正负整数和0的N×M矩阵,找到元素总和最大的子矩阵。返回一个数组[r1, c1, r2, c2]表示子矩阵的左上角和右下角坐标。题目改编自LeetCode,通过动态规划和最大子数组和求解。" 102488336,9038672,爬虫抓取策略:宽度优先与深度优先,"['爬虫技术', '网页抓取', '数据获取', '网络爬虫', '数据处理']
摘要由CSDN通过智能技术生成

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

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

注意:本题相对书上原题稍作改动

示例:

输入:
[
   [-1,0],
   [0,-1]
]
输出:[0,1,0,1]
解释:输入中标粗的元素即为输出所表示的矩阵
1
2
3
4
5
6
7
说明:

1 <= matrix.length, matrix[0].length <= 200
捕获2.JPG

 最大子序列和的二维化而已:

import java.util.Arrays;

class Solution {
    public int[] getMaxMatrix(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;
        int[] dp = new int[n];
        int max = Integer.MIN_VALUE;
        int[] result = new int[4];
        // 枚举子矩阵上界
        for (int i = 0; i < m; i++) {
            // 每次更换上界,需要将 dp 重置为 0
            Arrays.fill(arr, 0);
            // 枚举子矩阵下界
            for (int j = i; j < m; j++) {
                // 从左到右,计算子矩阵上下界之间的列和,第 k 列放到 dp[k] 中
                // 由于下界是逐行递增,每次只用把新增的一行累加到 dp 中即可
                for (int k = 0; k < n; k++) {
                    arr[k] += matrix[j][k];
                }
                // 计算列和数组 dp 的最大子序列和
                int[] lss = lss(arr);
                if (lss[0] > max) {
                    max = lss[0];
                    result = new int[]{i, lss[1], j, lss[2]};
                }
            }
        }
        return result;
    }

    // 最大子数组和,返回最大值和边界
    private int[] lss(int[] arr) {
        int max = Integer.MIN_VALUE, sum = Integer.MIN_VALUE;
        int[] result = new int[3];
        int start = 0;
        for (int i = 0; i < arr.length; i++) {
            if (sum < 0) {
                start = i;
                sum = arr[i];
            } else {
                sum = sum + arr[i];
            }
            if (sum > max) {
                result[0] = sum;
                result[1] = start;
                result[2] = i;
                max = sum;
            }
        }
        return result;
    }

}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值