import java.util.*;
/**
Maximum sub rectangle sum. r being number of rows and c being number of columts
running time os O(r^2c). Uses kadenes algorithm as a subroutine.
*/
public class MaximumRectangularSubmatrix{
public static void main(String... args){
System.out.println("starting maximum rectangular submatrix search");
int [][] arr =
{
{2,1,-3,-4,6},
{0,6,3,4,1},
{2,-2,-1,4,-5},
{-13,3,1,0,3}
};
int maximumSum = getMaximumRectangularAreaSum(arr);
System.out.println("maximum subrectangle sum=" + maximumSum);
}
/**
* all rows must be of same length. Size must be positive.
* sum must not overflow.
*/
public static int getMaximumRectangularAreaSum(int[][] arr){
int[] dummy = new int[arr.length];
int maxSum = 0;
int top = 0;
int bottom = 0;
int left = 0;
int right = 0;
for(int l = 0; l < arr[0].length ; l++){
Arrays.fill(dummy , 0);
for (int r = l ; r < arr[0].length ; r++){
for(int i = 0 ; i < arr.length ; i++){
dummy[i] += arr[i][r];
}
KadeneResult res = kadeneMaximumSum(dummy);
if(res.maxSum > maxSum){
maxSum = res.maxSum;
top = res.maxSumStart;
bottom = res.maxSumEnd;
left = l;
right = r;
}
}
}
System.out.println("left=" + left );
System.out.println("right=" + right );
System.out.println("bottom=" + bottom );
System.out.println("top=" + top );
return maxSum;
}
private static class KadeneResult{
int maxSumStart;
int maxSumEnd;
int maxSum;
}
public static KadeneResult kadeneMaximumSum(int [] arr){
KadeneResult result = new KadeneResult();
int maxWithMe = 0;
int maxWithMeStart = 0;
for(int i = 0; i < arr.length ; i++){
if(arr[i] > maxWithMe + arr[i])
maxWithMeStart = i;
maxWithMe = Math.max(maxWithMe + arr[i] , arr[i]);
if(maxWithMe > result.maxSum){
result.maxSum = maxWithMe;
result.maxSumStart = maxWithMeStart;
result.maxSumEnd = i;
}
}
return result;
}
}