package com.interview.dynamic; /** * Date 07/31/2014 * @author tusroy * * Write a program to find maximum sum rectangle in give 2D matrix. * Assume there is at least one positive number in the 2D matrix. * * Solution: * Keep temp array with size as number of rows. Start left and right from 0 * and keep adding values for each row and maintain them in this temp array. * Run Kadane's algorithm to find max sum subarray in temp. Now increment right by * 1. When right reaches last column reset right to 1 and left to 1. * * Space complexity of this algorithm is O(row) * Time complexity of this algorithm is O(row*col*col) * * References * http://www.geeksforgeeks.org/dynamic-programming-set-27-max-sum-rectangle-in-a-2d-matrix/ */ public class SubRectangularMatrixWithMaximumSum { class Result{ int maxSum; int leftBound; int rightBound; int upBound; int lowBound; @Override public String toString() { return "Result [maxSum=" + maxSum + ", leftBound=" + leftBound + ", rightBound=" + rightBound + ", upBound=" + upBound + ", lowBound=" + lowBound + "]"; } } public Result maxSum(int input[][]){ int rows = input.length; int cols = input[0].length; int temp[] = new int[rows]; Result result = new Result(); for(int left = 0; left < cols ; left++){ for(int i=0; i < rows; i++){ temp[i] = 0; } for(int right = left; right < cols; right++){ for(int i=0; i < rows; i++){ temp[i] += input[i][right]; } KadaneResult kadaneResult = kadane(temp); if(kadaneResult.maxSum > result.maxSum){ result.maxSum = kadaneResult.maxSum; result.leftBound = left; result.rightBound = right; result.upBound = kadaneResult.start; result.lowBound = kadaneResult.end; } } } return result; } class KadaneResult{ int maxSum; int start; int end; public KadaneResult(int maxSum, int start, int end) { this.maxSum = maxSum; this.start = start; this.end = end; } } private KadaneResult kadane(int arr[]){ int max = 0; int maxStart = -1; int maxEnd = -1; int currentStart = 0; int maxSoFar = 0; for(int i=0; i < arr.length; i++){ maxSoFar += arr[i]; if(maxSoFar < 0){ maxSoFar = 0; currentStart = i+1; } if(max < maxSoFar){ maxStart = currentStart; maxEnd = i; max = maxSoFar; } } return new KadaneResult(max, maxStart, maxEnd); } public static void main(String args[]){ int input[][] = {{ 2, 1, -3, -4, 5}, { 0, 6, 3, 4, 1}, { 2, -2, -1, 4, -5}, {-3, 3, 1, 0, 3}}; SubRectangularMatrixWithMaximumSum saw = new SubRectangularMatrixWithMaximumSum(); System.out.println(saw.maxSum(input)); } }