leetcode 1074

问题

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:

1
2
3
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:

1
2
3
Input: matrix = [[1,-1],[-1,1]], target = 0
Output: 5
Explanation: The two 1x2 submatrices, plus the two 2x1 submatrices, plus the 2x2 submatrix.

Note:

  1. 1 <= matrix.length <= 300
  2. 1 <= matrix[0].length <= 300
  3. -1000 <= matrix[i] <= 1000
  4. -10^8 <= target <= 10^8

分析

先对每一行求前缀和,然后再确定每一对可能的列,这样在确定了每一列求解时,就转化为了Find the Subarray with Target Sum 的问题。时间复杂度$O(N^2M)$。

总结:二维数组中查找子矩阵的处理方案除了固定每个右下角再进行子问题分解之外,还可以通过固定每两个确定的行或者列来分解子问题,思路与之前一道查找四个顶点都是 1 的 submatrix 的题目的处理方法比较像。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
public:
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
int m = matrix.size();
int n = matrix[0].size();

for (int i = 0; i < m; ++i) {
for (int j = 1; j < n; ++j) {
matrix[i][j] += matrix[i][j-1];
}
}

int ans = 0;
unordered_map<int,int> mp;
for (int i = 0; i < n; ++i) {
for (int j = i; j < n; ++j) {
mp.clear();
int sum = 0;
mp[0] = 1;
for (int k = 0; k < m; ++k) {
sum += matrix[k][j]-(i==0? 0: matrix[k][i-1]);
// 不判断在不在而直接相加会TLE
if (mp.find(sum - target) != mp.end())
ans += mp[sum - target];

mp[sum]++;
}
}
}
return ans;
}
};