[Coding Made Simple] Maximum Sum Rectangular Submatrix in Matrix

Given a 2D matrix of  integers, find maximum sum rectangle in this matrix.

 

Brute force solution of enumerating all possible submatrix then check their sum is too inefficient. 

 

Algorithm of using the Kadane's algorithm(Maximum Subarray)

1. Fix a left and right column range to get a submatrix, there are O(col * col) such submatrices to consider.

2. For each submatrix, use a 1D array to get its total sum in O(row) time(dynamic programming used to avoid starting each computation from scratch).

    Then apply the Kadane's algorithm to get the maximum subarray sum on this 1D array in O(row) time. Because this 1D array represents the total

  sum of the current submatrix, the max subarray sum from this 1D array represents the max rectangular submatrix sum of the current submatrix.

 

O(col * col * row) runtime, O(row) space

  1 import java.util.ArrayList;
  2 
  3 class Point {
  4     int row, col;
  5     Point(int r, int c) {
  6         row = r;
  7         col = c;
  8     }
  9     void display() {
 10         System.out.println(this.row + ", " + this.col);
 11     }
 12 }
 13 public class MaxRectangleSum {
 14     private ArrayList<Point> maxRecCoordinates = null;
 15     public int getMaxRecSum(int[][] matrix) {
 16         if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
 17             return 0;
 18         }
 19         maxRecCoordinates = new ArrayList<Point>();
 20         int max = Integer.MIN_VALUE, x = 0, y = 0;
 21         boolean hasPositiveInt = false;
 22         
 23         //preprocess matrix for case of no positive integer present
 24         for(int i = 0; i < matrix.length; i++) {
 25             for(int j = 0; j < matrix[0].length; j++) {
 26                 if(matrix[i][j] > 0) {
 27                     hasPositiveInt = true;
 28                     break;
 29                 }
 30                 else if(matrix[i][j] > max){
 31                     max = matrix[i][j];
 32                     x = i;
 33                     y = j;
 34                 }
 35             }
 36         }
 37         if(!hasPositiveInt) {
 38             for(int i = 0; i < 2; i++) {
 39                 maxRecCoordinates.add(new Point(x, y));
 40             }
 41             return max;
 42         }
 43         
 44         max = Integer.MIN_VALUE;
 45         int[] range= new int[2];
 46         int maxLeft = 0, maxRight = 0, maxTop = 0, maxBottom = 0;
 47         int[] colArr = new int[matrix.length];
 48         for(int l = 0; l < matrix[0].length; l++) {
 49             for(int i = 0; i < matrix.length; i++) {
 50                 colArr[i] = 0;
 51             }
 52             for(int r = l; r < matrix[0].length; r++) {
 53                 for(int i = 0; i < matrix.length; i++) {
 54                     colArr[i] += matrix[i][r]; 
 55                 }
 56                 int currSum = getMaxSubarraySum(colArr, range);
 57                 if(currSum > max) {
 58                     max = currSum;
 59                     maxLeft = l;
 60                     maxRight = r;
 61                     maxTop = range[0];
 62                     maxBottom = range[1];
 63                 }
 64             }
 65         }
 66         Point topLeft = new Point(maxTop, maxLeft);
 67         Point bottomRight = new Point(maxBottom, maxRight);
 68         maxRecCoordinates.add(topLeft);
 69         maxRecCoordinates.add(bottomRight);
 70         return max;
 71     }
 72     private int getMaxSubarraySum(int[] arr, int[] range) {
 73         range[0] = 0;
 74         range[1] = 0;
 75         int currSum = 0, minSum = 0, maxSum = Integer.MIN_VALUE;
 76         int minSumEndIdx = -1;
 77         for(int i = 0; i < arr.length; i++) {
 78             currSum += arr[i];
 79             if(currSum - minSum > maxSum) {
 80                 maxSum = currSum - minSum;
 81                 range[0] = minSumEndIdx + 1;
 82                 range[1] = i;
 83             }
 84             if(currSum < minSum) {
 85                 minSum = currSum;
 86                 minSumEndIdx = i;
 87             }
 88         }
 89         return maxSum;
 90     }
 91     public static void main(String[] args) {
 92         int[][] matrix1 = {{2,1,-3,-4,5}, {0,6,3,4,1},{2,-2,-1,4,-5},{-3,3,1,0,3}};
 93         int[] arr = {-2,2,-3,4,-1,2,1,-5,3};
 94         int[] range = new int[2];
 95         MaxRectangleSum test = new MaxRectangleSum();
 96         System.out.println(test.getMaxSubarraySum(arr, range));
 97         for(int i = 0; i < 2; i++) {
 98             System.out.println(range[i]);
 99         }
100         System.out.println(test.getMaxRecSum(matrix1));
101         for(int i = 0; i < test.maxRecCoordinates.size(); i++) {
102             test.maxRecCoordinates.get(i).display();
103         }
104     }
105 }

 

 

Related Problems 

[LintCode] Maximum Subarray

Submatrix Sum To Zero

转载于:https://www.cnblogs.com/lz87/p/7288814.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值