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]]
The core challenge of this problem is to identify 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 any domain where analyzing sub-regions of a matrix is crucial. A common pitfall is to assume that the submatrix must be contiguous in both rows and columns, which is indeed the case here.
To solve this problem, we can use a dynamic programming approach combined with the concept of prefix sums. The naive solution would involve checking all possible submatrices, which is computationally expensive with a time complexity of O(m^3 * n^3). Instead, we can optimize this by reducing the problem to a series of 1D maximum subarray problems (Kadane's algorithm).
1. **Prefix Sum Calculation**: First, we calculate the prefix sums for each row to quickly compute the sum of any submatrix. 2. **Kadane's Algorithm**: For each pair of rows, we use Kadane's algorithm to find the maximum sum subarray for the columns between these rows.
1. Compute the prefix sums for each row. 2. Iterate over all pairs of rows. 3. For each pair of rows, use Kadane's algorithm to find the maximum sum subarray for the columns between these rows. 4. Keep track of the maximum sum found.
#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) {
// Use Kadane's algorithm to find the maximum sum subarray
int currentSum = 0;
int maxSubarraySum = INT_MIN;
for (int col = 0; col < n; ++col) {
int colSum = prefixSum[bottom][col + 1] - prefixSum[top][col + 1];
currentSum = max(colSum, currentSum + colSum);
maxSubarraySum = max(maxSubarraySum, currentSum);
}
maxSum = max(maxSum, maxSubarraySum);
}
}
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;
}
The time complexity of this approach is O(m^2 * n) because we iterate over all pairs of rows (O(m^2)) and for each pair, we apply Kadane's algorithm on the columns (O(n)). The space complexity is O(m * n) due to the prefix sum matrix.
Potential edge cases include:
To test the solution comprehensively, consider the following test cases:
When approaching such problems:
Understanding and solving the maximum sum submatrix problem is crucial for various applications. By breaking down the problem and using efficient algorithms like Kadane's, we can significantly optimize our solution. Practice and familiarity with dynamic programming and prefix sums are key to mastering such problems.
For further reading and practice: