Number of Submatrices That Sum to Target
HARDDescription
Given a matrix and a target, return the number of non-empty submatrices that sum to target.
A submatrix x1, y1, x2, y2 is the set of all cells matrix[x][y] with x1 <= x <= x2 and y1 <= y <= y2.
Two submatrices (x1, y1, x2, y2) and (x1', y1', x2', y2') are different if they have some coordinate that is different: for example, if x1 != x1'.
Example 1:
Input: matrix = [[0,1,0],[1,1,1],[0,1,0]], target = 0 Output: 4 Explanation: The four 1x1 submatrices that only contain 0.
Example 2:
Input: matrix = [[1,-1],[-1,1]], target = 0 Output: 5 Explanation: The two 1x2 submatrices, plus the two 2x1 submatrices, plus the 2x2 submatrix.
Example 3:
Input: matrix = [[904]], target = 0 Output: 0
Constraints:
1 <= matrix.length <= 1001 <= matrix[0].length <= 100-1000 <= matrix[i][j] <= 1000-10^8 <= target <= 10^8
Approaches
Checkout 3 different approaches to solve Number of Submatrices That Sum to Target. Click on different approaches to view the approach and algorithm in detail.
Optimized Sum Calculation with 2D Prefix Sum
This approach improves upon the brute-force method by pre-calculating a 2D prefix sum matrix. This allows us to find the sum of any submatrix in constant time, reducing the overall complexity.
Algorithm
- Create a 2D prefix sum matrix
prefixSumof size(rows+1) x (cols+1). - Populate
prefixSumin O(R * C) time. - Initialize a counter
countto 0. - Iterate through all possible top-left
(r1, c1)and bottom-right(r2, c2)corners of submatrices. - For each submatrix, calculate its sum in O(1) using the
prefixSummatrix. - If the sum equals
target, incrementcount. - Return
count.
First, we create a prefixSum matrix of size (rows + 1) x (cols + 1). prefixSum[i][j] will store the sum of the rectangle from (0, 0) to (i-1, j-1). This prefixSum matrix can be computed in O(R * C) time using the formula: prefixSum[i][j] = matrix[i-1][j-1] + prefixSum[i-1][j] + prefixSum[i][j-1] - prefixSum[i-1][j-1]. After the prefixSum matrix is built, we iterate through all possible submatrices using four nested loops, just like in the brute-force approach. However, instead of calculating the sum with two extra loops, we use the prefixSum matrix to get the sum in O(1) time. The sum of the submatrix from (r1, c1) to (r2, c2) is given by prefixSum[r2+1][c2+1] - prefixSum[r1][c2+1] - prefixSum[r2+1][c1] + prefixSum[r1][c1]. If this sum equals the target, we increment our count.
class Solution {
public int numSubmatrixSumTarget(int[][] matrix, int target) {
int rows = matrix.length;
int cols = matrix[0].length;
int count = 0;
// Create and compute the 2D prefix sum matrix
int[][] prefixSum = new int[rows + 1][cols + 1];
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= cols; j++) {
prefixSum[i][j] = matrix[i - 1][j - 1] + prefixSum[i - 1][j] + prefixSum[i][j - 1] - prefixSum[i - 1][j - 1];
}
}
// Iterate over all possible submatrices
for (int r1 = 1; r1 <= rows; r1++) {
for (int c1 = 1; c1 <= cols; c1++) {
for (int r2 = r1; r2 <= rows; r2++) {
for (int c2 = c1; c2 <= cols; c2++) {
// Calculate sum in O(1) using prefix sum matrix
int sum = prefixSum[r2][c2] - prefixSum[r1 - 1][c2] - prefixSum[r2][c1 - 1] + prefixSum[r1 - 1][c1 - 1];
if (sum == target) {
count++;
}
}
}
}
}
return count;
}
}
Complexity Analysis
Pros and Cons
- Significantly faster than the pure brute-force approach.
- Reduces the sum calculation from O(R*C) to O(1).
- Still too slow for the given constraints, as O(R^2 * C^2) is too large.
- Uses extra space for the prefix sum matrix.
Code Solutions
Checking out 3 solutions in different languages for Number of Submatrices That Sum to Target. Click on different languages to view the code.
class Solution {
public
int numSubmatrixSumTarget(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int ans = 0;
for (int i = 0; i < m; ++i) {
int[] col = new int[n];
for (int j = i; j < m; ++j) {
for (int k = 0; k < n; ++k) {
col[k] += matrix[j][k];
}
ans += f(col, target);
}
}
return ans;
}
private
int f(int[] nums, int target) {
Map<Integer, Integer> d = new HashMap<>();
d.put(0, 1);
int s = 0, cnt = 0;
for (int x : nums) {
s += x;
cnt += d.getOrDefault(s - target, 0);
d.merge(s, 1, Integer : : sum);
}
return cnt;
}
}
Video Solution
Watch the video walkthrough for Number of Submatrices That Sum to Target
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.