lintcode 1489 · 最大矩阵边界和 【前缀和数组 中等 vip】

题目

https://www.lintcode.com/problem/1489

java 复制代码
给定一个大小
n∗m的矩阵arr,从arr中找出一个非空子矩阵,使位于这个子矩阵边界上的元素之和最大。输出该子矩阵的边界上的元素之和。

1≤n,m≤200

−10 ^3 ≤arr[i][j]≤10 ^3
 
样例
样例1

输入: arr=[[-1,-3,2],[2,3,4],[-3,7,2]]
输出: 16
样例说明: 子矩阵[[3,4],[7,2]]的轮廓元素之和最大.
样例2

-1
最大的。
样例3

输入: arr=[1,1,1],[1,2,1],[1,1,1]
输出: 8
样例说明:选取整个矩阵,轮廓和为8,最大。

思路

复制代码
	 prefixSum + enumeration
    for each row and column, set up the prefixSum Array:

    rowPrefixSumArray[n][m+1] : for each row, record the prefix sumarray of [0..n-1][0..m]
    colPrefixSumArray[m][n+1] : for each column, record the prefix sum array of [0..m-1][0..n]

    for (i1 = 0..n-1, j1=0..m-1)
        for (i2 = i1..n-1, j2=j1..m-1)
            maxSum = max(maxSum, calcBoundarySum(i1, j1, i2, j2))
    return maxSum

    T=O(n * m)^2), S=O(n * m)

代码

java 复制代码
public class Solution {
    /**
     * @param arr: the matrix
     * @return: Return the largest sum of the matrix boundary elements
     */
    public int solve(int[][] arr) {
             /*
        prefixSum + enumeration
        for each row and column, set up the prefixSum Array:

        rowPrefixSumArray[n][m+1] : for each row, record the prefix sumarray of [0..n-1][0..m]
        colPrefixSumArray[m][n+1] : for each column, record the prefix sum array of [0..m-1][0..n]

        for (i1 = 0..n-1, j1=0..m-1)
            for (i2 = i1..n-1, j2=j1..m-1)
                maxSum = max(maxSum, calcBoundarySum(i1, j1, i2, j2))
        return maxSum

        T=O(n * m)^2), S=O(n * m)
        */
        if (arr == null || arr.length == 0 || arr[0] == null || arr[0].length == 0)
            return 0;
        int n = arr.length, m = arr[0].length;
        int[][] rowPreSum = createRPS(arr, n, m);  //每一行的前缀和
        int[][] colPreSum = createCPS(arr, n, m);  //没一列的前缀和

        int maxSum = Integer.MIN_VALUE;
        for (int i1 = 0; i1 < n; i1++) {
            for (int j1 = 0; j1 < m; j1++) {
                for (int i2 = i1; i2 < n; i2++) {
                    for (int j2 = j1; j2 < m; j2++) {
                        int curMatrixSum = f(arr, rowPreSum, colPreSum, i1, j1, i2, j2);
                        maxSum = Math.max(maxSum, curMatrixSum);
                    }
                }
            }
        }
        return maxSum;
    }

    /*
     -1 -3 2
     2 3 4
     -3 7 2

     rowPreSum:
     0 -1 -4 -2
     0 2 5 9
     0 -3 4 6

     colPreSum:
     0 0   0
     -1 -3 2
     1  0. 6
     -2 7. 8
     */
    public static int[][] createRPS(int[][] arr, int n, int m) {
        int[][] sum = new int[n][m + 1];
        for (int row = 0; row < n; row++) {
            sum[row][0] = 0; //可以不设置,默认就是0
            for (int col = 1; col <= m; col++) {
                sum[row][col] = sum[row][col - 1] + arr[row][col - 1];
            }
        }

        return sum;
    }

    public static int[][] createCPS(int[][] arr, int n, int m) {
        int[][] sum = new int[n + 1][m];
        for (int col = 0; col < m; col++) {
            sum[0][col] = 0;//可以不设置,默认值是0
            for (int row = 1; row <= n; row++) {
                sum[row][col] = sum[row - 1][col] + arr[row - 1][col];
            }
        }

        return sum;
    }
        /*
                  j1      j2
        i1 :      X        X

        i2 :      X        X
        */

    public static int f(int[][] arr, int[][] rowSum, int[][] colSum, int i1, int j1, int i2, int j2) {
        int sum = 0;
        sum += rowSum[i1][j2 + 1] - rowSum[i1][j1];  //row: i1 (j1..j2)
        if (i1 == i2) return sum;

        //row: i2 (j1..j2)
        sum += rowSum[i2][j2 + 1] - rowSum[i2][j1];

        // col j1, row: i1+1, i2-1: colSum[i2-1+1][j1]  -  colSum[i1+1][j1] (i1< i1+1 <= i2-1 < i2)
        // col j2, row: i1+1, i2-1: colSum[i2-1+1][j2]  -  colSum[i1+1][j2] (i1< i1+1 <= i2-1 < i2)

        if (i1 < i2-1) {
            sum += colSum[i2][j1] - colSum[i1 + 1][j1];
            sum += colSum[i2][j2] - colSum[i1 + 1][j2];
        }
        return sum;
    }
}
相关推荐
王老师青少年编程16 分钟前
信奥赛C++提高组csp-s之欧拉回路
c++·算法·csp·欧拉回路·信奥赛·csp-s·提高组
墨有66624 分钟前
数学分析栈的出栈顺序:从算法判断到数学本质(卡特兰数初探)
c++·算法·数学建模
zhutoutoutousan28 分钟前
氛围数学学习:用游戏化思维征服抽象数学
学习·算法·游戏
victory043141 分钟前
pytorch 矩阵乘法和实际存储形状的差异
人工智能·pytorch·矩阵
guygg8842 分钟前
基于捷联惯导与多普勒计程仪组合导航的MATLAB算法实现
开发语言·算法·matlab
fengfuyao98543 分钟前
遗传算法与粒子群算法求解非线性函数最大值问题
算法
LeetCode天天刷1 小时前
【软件认证】比特翻转【滑动窗口】
算法
源代码•宸1 小时前
Leetcode—1123. 最深叶节点的最近公共祖先【中等】
经验分享·算法·leetcode·职场和发展·golang·dfs
s砚山s1 小时前
代码随想录刷题——二叉树篇(十三)
数据结构·算法
alphaTao1 小时前
LeetCode 每日一题 2026/1/5-2026/1/11
算法·leetcode