zoukankan      html  css  js  c++  java
  • [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

  • 相关阅读:
    用户空间与内核空间,进程上下文与中断上下文[总结]【转】
    select、poll、epoll之间的区别总结[整理]【转】
    v4l2驱动文档之——streaming IO【转】
    Linux网络编程一步一步学【转】
    V4L2驱动的移植与应用(二+三)【转】
    【PHP面向对象(OOP)编程入门教程】20.PHP5接口技术(interface)
    【PHP面向对象(OOP)编程入门教程】19.抽象方法和抽象类(abstract)
    【PHP面向对象(OOP)编程入门教程】18.__call()处理调用错误
    【PHP面向对象(OOP)编程入门教程】17.克隆对象__clone()方法
    【PHP面向对象(OOP)编程入门教程】16.__toString()方法
  • 原文地址:https://www.cnblogs.com/lz87/p/7288814.html
Copyright © 2011-2022 走看看