Start learning free

LESSON 235 OF 409 · PARTIAL SUMS #2

Maximum Sum Submatrix II - Time Complexity: O(m^2 * n) - C++ Solution

Practice O(n2 * m2) 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 17
    Ctrl + Enter to check

    C++ · PARTIAL SUMS #2

    Maximum Sum Submatrix in C++, 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 can use a dynamic programming approach combined with the concept of prefix sums. Here's a step-by-step breakdown:

    Naive Solution

    A naive solution would involve checking all possible submatrices and calculating their sums. This approach is not optimal due to its high time complexity of O(m^2 * n^2 * min(m, n)).

    Optimized Solution

    We can optimize the solution by using prefix sums and Kadane's algorithm. The idea is to reduce the problem to a series of 1D maximum subarray sum problems.

    Steps:

    1. Calculate the prefix sums for each row.
    2. For each pair of rows, use the prefix sums to create a 1D array representing the sum of elements between these two rows for each column.
    3. Apply Kadane's algorithm on this 1D array to find the maximum subarray sum.
    4. Keep track of the maximum sum found.

    Algorithm

    Here is a detailed breakdown of the algorithm:

    1. Initialize a variable to store the maximum sum.
    2. Compute the prefix sums for each row.
    3. Iterate over all pairs of rows.
    4. For each pair of rows, create a 1D array of column sums between these rows.
    5. Use Kadane's algorithm to find the maximum subarray sum for this 1D array.
    6. Update the maximum sum if a larger sum is found.

    Code Implementation

    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    // Function to find the maximum sum submatrix
    int maxSumSubmatrix(vector<vector<int>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        int maxSum = INT_MIN;
    
        // Prefix sums for each row
        vector<vector<int>> prefixSum(m, vector<int>(n + 1, 0));
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                prefixSum[i][j + 1] = prefixSum[i][j] + matrix[i][j];
            }
        }
    
        // Iterate over all pairs of rows
        for (int top = 0; top < m; ++top) {
            for (int bottom = top; bottom < m; ++bottom) {
                // 1D array to store the sum of elements between the two rows for each column
                vector<int> colSum(n, 0);
                for (int col = 0; col < n; ++col) {
                    colSum[col] = prefixSum[bottom][col + 1] - prefixSum[top][col];
                }
    
                // Apply Kadane's algorithm to find the maximum subarray sum
                int currentMax = colSum[0];
                int currentSum = colSum[0];
                for (int k = 1; k < n; ++k) {
                    currentSum = max(colSum[k], currentSum + colSum[k]);
                    currentMax = max(currentMax, currentSum);
                }
    
                // Update the maximum sum
                maxSum = max(maxSum, currentMax);
            }
        }
    
        return maxSum;
    }
    
    int main() {
        vector<vector<int>> matrix = {
            {1, -9, -10, 1},
            {-1, 10, 10, 1},
            {0, 9, 9, -9},
            {-1, -1, -1, -1}
        };
    
        cout << "Maximum Sum Submatrix: " << maxSumSubmatrix(matrix) << endl;
        return 0;
    }
    

    Complexity Analysis

    The time complexity of this approach 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(m * n) due to the prefix sums array.

    Edge Cases

    Potential edge cases include:

    • All elements are negative.
    • The matrix contains only one element.
    • Rows or columns with zero sums.

    Each of these cases is handled by the algorithm, ensuring it returns the correct maximum sum.

    Testing

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

    • Simple cases with small matrices.
    • Cases with all negative numbers.
    • Large matrices to test performance.

    Using a testing framework like Google Test can help automate and validate these test cases.

    Thinking and Problem-Solving Tips

    When approaching such problems, consider breaking them down into smaller subproblems. Use dynamic programming and prefix sums to simplify complex calculations. Practice similar problems to improve your problem-solving skills.

    Conclusion

    Understanding and solving the maximum sum submatrix problem is crucial for various applications. By using optimized algorithms like Kadane's algorithm and prefix sums, we can efficiently find the solution. Practice and exploration of similar problems will further enhance your skills.

    Additional Resources

    For further reading and practice, consider the following resources:

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