Start learning free

LESSON 237 OF 410 · PARTIAL SUMS #2

Maximum Sum Submatrix III - Time Complexity: O(m^2 * n) - Java Solution

Practice O(n2 * m) Read the full explanation

Given a m x n grid filled with integers, find the submatrix with maximum sum among all submatrices.

Example:

Input:
[
  [ 1,  -9, -10,  1],
  [-1,  10,  10,  1],
  [ 0,   9,   9, -9],
  [-1,  -1,  -1, -1]
]
Output: 38
Explanation: Submatrix [[10, 10], [9, 9]]
STEP 1 OF 20
    Ctrl + Enter to check

    JAVA · PARTIAL SUMS #2

    Maximum Sum Submatrix in Java, explained

    Understanding the Problem

    The core challenge of this problem is to find the submatrix within a given m x n grid that has the maximum sum. This problem is significant in various applications such as image processing, financial analysis, and more. A common pitfall is to consider only submatrices of fixed sizes or to overlook negative values that might affect the sum.

    Approach

    To solve this problem, we need to consider all possible submatrices and calculate their sums. A naive approach would involve iterating over all possible submatrices, which would be computationally expensive. Instead, we can use a more optimized approach leveraging the concept of prefix sums and Kadane's algorithm.

    Naive Solution

    The naive solution involves iterating over all possible submatrices and calculating their sums. This approach has a time complexity of O(m^2 * n^2), which is not feasible for large grids.

    Optimized Solution

    The optimized solution involves the following steps:

    1. Use prefix sums to quickly calculate the sum of any submatrix.
    2. Apply Kadane's algorithm to find the maximum sum subarray for each pair of rows.

    This approach reduces the time complexity to O(m^2 * n), making it more efficient for larger grids.

    Algorithm

    Here is a step-by-step breakdown of the optimized algorithm:

    1. Initialize a variable to store the maximum sum.
    2. Iterate over all pairs of rows.
    3. For each pair of rows, use a temporary array to store the sum of elements between these rows for each column.
    4. Apply Kadane's algorithm on this temporary array to find the maximum sum subarray.
    5. Update the maximum sum if the current subarray sum is greater.

    Code Implementation

    public class MaximumSumSubmatrix {
        public int maxSumSubmatrix(int[][] matrix) {
            int m = matrix.length;
            int n = matrix[0].length;
            int maxSum = Integer.MIN_VALUE;
    
            // Iterate over all pairs of rows
            for (int top = 0; top < m; top++) {
                int[] temp = new int[n];
                for (int bottom = top; bottom < m; bottom++) {
                    // Calculate the sum of elements between the top and bottom rows for each column
                    for (int col = 0; col < n; col++) {
                        temp[col] += matrix[bottom][col];
                    }
                    // Find the maximum sum subarray in temp using Kadane's algorithm
                    maxSum = Math.max(maxSum, kadane(temp));
                }
            }
            return maxSum;
        }
    
        // Helper function to find the maximum sum subarray using Kadane's algorithm
        private int kadane(int[] array) {
            int maxEndingHere = array[0];
            int maxSoFar = array[0];
            for (int i = 1; i < array.length; i++) {
                maxEndingHere = Math.max(array[i], maxEndingHere + array[i]);
                maxSoFar = Math.max(maxSoFar, maxEndingHere);
            }
            return maxSoFar;
        }
    
        public static void main(String[] args) {
            MaximumSumSubmatrix solution = new MaximumSumSubmatrix();
            int[][] matrix = {
                {1, -9, -10, 1},
                {-1, 10, 10, 1},
                {0, 9, 9, -9},
                {-1, -1, -1, -1}
            };
            System.out.println(solution.maxSumSubmatrix(matrix)); // Output: 38
        }
    }
    

    Complexity Analysis

    The time complexity of the optimized solution is O(m^2 * n) because we iterate over all pairs of rows and apply Kadane's algorithm on each pair. The space complexity is O(n) for the temporary array used to store column sums.

    Edge Cases

    Potential edge cases include:

    • All elements are negative: The algorithm should still find the submatrix with the least negative sum.
    • Single row or single column matrix: The algorithm should handle these cases correctly.

    To test these edge cases, we can use the following examples:

    int[][] matrix1 = {{-1, -2, -3}, {-4, -5, -6}, {-7, -8, -9}};
    int[][] matrix2 = {{1, 2, 3}};
    int[][] matrix3 = {{1}, {2}, {3}};
    

    Testing

    To test the solution comprehensively, we should include a variety of test cases:

    • Small matrices with positive and negative values.
    • Large matrices to test performance.
    • Edge cases such as single row or column matrices.

    We can use JUnit or any other testing framework to automate these tests.

    Thinking and Problem-Solving Tips

    When approaching such problems, it is essential to:

    • Break down the problem into smaller parts.
    • Consider both naive and optimized solutions.
    • Use well-known algorithms like Kadane's algorithm to simplify the problem.
    • Practice similar problems to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed how to find the maximum sum submatrix in a given m x n grid. We explored both naive and optimized solutions, provided a detailed algorithm, and implemented the solution in Java. Understanding and solving such problems is crucial for improving problem-solving skills and preparing for coding interviews.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with JavaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free