Max subarray, and Max sub rectangle

By | June 27, 2016
Share the joy
  •  
  •  
  •  
  •  
  •  
  •  

Max subarray is from here: https://en.wikipedia.org/wiki/Maximum_subarray_problem

Finding the contiguous subarray within a one-dimensional array of numbers which has the largest sum. For example, for the sequence of values −2, 1, −3, 4, −1, 2, 1, −5, 4; the contiguous subarray with the largest sum is 4, −1, 2, 1, with sum 6.

This is a classical problem which can be solved by Kadane algorithm. Below is the java solution:

public static int maxSubArray(int []arr) {
    int max = arr[0], currMax = arr[0];
    for (int i = 1; i < arr.length; i++) {
        currMax = Math.max(currMax + arr[i], arr[i]);  // compare the history continuous sum and current value
        max = Math.max(max, currMax);  // update the max
    }
    return max;
}

However, this problem can be developed to 2d problem: Given a 2D array, find the maximum sum subarray in it. For example, in the following 2D array, the maximum sum subarray is highlighted with blue rectangle and sum of this subarray is 29. (http://www.geeksforgeeks.org/dynamic-programming-set-27-max-sum-rectangle-in-a-2d-matrix/)

A great solution can be found in Tushar’s tutorial. In the solution, the outer loop iterates the column(left, right). Then it calculates the 1-dimension helper array which is sum of all elements from column left to column right. Then run the Kadane’s algorithm on this helper array.

Below is my java code:

public static int maxSubArrayRectangle(int [][]arr) {
    int row = arr.length, col = arr[0].length, max = arr[0][0];
    int[] helperArr = null;
    for (int left = 0; left < col; left++) {
        helperArr = new int[col];
        for (int right = left; right < col; right++) {
            // update helper
            for (int i = 0; i < row; i++) {
                helperArr[i] += arr[i][right];
            }
            // Kodane algorithm to find the top and bottom for max continuous sequence
            int helperMax = helperArr[0], currHelperMax = helperArr[0];
            for (int i = 0; i < row; i++) {
                currHelperMax = Math.max(currHelperMax + helperArr[i], helperArr[i]);
                helperMax = Math.max(helperMax, currHelperMax);
            }
            max = Math.max(currHelperMax, max);
        }
    }
    return max;
}

Check my code on github: Max subarrayMax sub rectangle