Start learning free

LESSON 237 OF 410 · PARTIAL SUMS #2

Maximum Sum Submatrix III in Python (Time Complexity: O(m^2 * n^2))

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

    PYTHON · PARTIAL SUMS #2

    Maximum Sum Submatrix in Python, 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 assume that the submatrix must be of a fixed size, but it can be of any size within the given grid.

    Approach

    To solve this problem, we can use a dynamic programming approach combined with the concept of prefix sums. Here's a step-by-step breakdown:

    Naive Solution

    The naive solution involves checking all possible submatrices and calculating their sums. This approach is not optimal due to its high time complexity of O(m^3 * n^3).

    Optimized Solution

    We can optimize the solution by using prefix sums to reduce the time complexity to O(m^2 * n^2). The idea is to precompute the sum of elements in submatrices starting from the top-left corner to any point (i, j) in the grid. This allows us to quickly calculate the sum of any submatrix using the inclusion-exclusion principle.

    Algorithm

    1. Compute the prefix sum matrix.

    2. Iterate over all possible pairs of rows.

    3. For each pair of rows, use a sliding window technique to find the maximum sum subarray for the columns between these rows.

    Code Implementation

    def max_sum_submatrix(matrix):
        # Step 1: Compute the prefix sum matrix
        m, n = len(matrix), len(matrix[0])
        prefix_sum = [[0] * (n + 1) for _ in range(m + 1)]
        
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                prefix_sum[i][j] = matrix[i-1][j-1] + prefix_sum[i-1][j] + prefix_sum[i][j-1] - prefix_sum[i-1][j-1]
        
        # Step 2: Initialize the maximum sum to a very small number
        max_sum = float('-inf')
        
        # Step 3: Iterate over all pairs of rows
        for r1 in range(1, m + 1):
            for r2 in range(r1, m + 1):
                # Step 4: Use a sliding window to find the maximum sum subarray for the columns between these rows
                current_sum = 0
                for col in range(1, n + 1):
                    # Calculate the sum of the submatrix from row r1 to r2 and column 1 to col
                    submatrix_sum = prefix_sum[r2][col] - prefix_sum[r1-1][col]
                    current_sum = max(submatrix_sum, current_sum + submatrix_sum)
                    max_sum = max(max_sum, current_sum)
        
        return max_sum
    
    # Example usage
    matrix = [
        [1, -9, -10, 1],
        [-1, 10, 10, 1],
        [0, 9, 9, -9],
        [-1, -1, -1, -1]
    ]
    print(max_sum_submatrix(matrix))  # Output: 38
    

    Complexity Analysis

    The time complexity of this approach is O(m^2 * n^2) because we iterate over all pairs of rows and use a sliding window technique for the columns. The space complexity is O(m * n) due to the prefix sum matrix.

    Edge Cases

    Potential edge cases include:

    • All elements are negative.
    • The grid has only one row or one column.
    • The grid is empty.

    Each of these cases should be tested to ensure the algorithm handles them correctly.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Simple cases with small grids.
    • Grids with all positive or all negative numbers.
    • Grids with mixed positive and negative numbers.
    • Edge cases such as single row, single column, and empty grid.

    Thinking and Problem-Solving Tips

    When approaching such problems, it's essential to break down the problem into smaller parts and think about how to optimize each part. Practice solving similar problems and study different algorithms to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed how to find the submatrix with the maximum sum in a given m x n grid. We explored a naive solution and an optimized solution using prefix sums and a sliding window technique. Understanding and solving such problems is crucial for developing strong problem-solving skills in programming.

    Additional Resources

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