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


    题目

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

    给定一个大小
    n∗m的矩阵arr,从arr中找出一个非空子矩阵,使位于这个子矩阵边界上的元素之和最大。输出该子矩阵的边界上的元素之和。
    
    1≤n,m≤20010 ^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,最大。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    思路

    	 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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    代码

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
  • 相关阅读:
    LeetCode算法练习top100:(4)链表
    常用命令(Linux、Git、g++、gdb)
    VK1088B 22*4点 LCD液晶显示屏驱动IC,4*4MM超小体积,具省电模式,多用于超小型LCD段码屏显示驱动,FAE技术支持
    初学python第一天
    展会预告 | 图扑邀您共聚 IOTE 国际物联网展·深圳站
    GC-垃圾回收
    【C语言】函数的定义、传参与调用(二)
    理解 Linux backlog/somaxconn 内核参数
    ConsulManager安装
    每日三题 8.19
  • 原文地址:https://blog.csdn.net/weixin_37991016/article/details/132817197