Leetocde 1074 Number of Submatrices That Sum to Target (动态规划) (滑动窗口)
问题描述
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.
Note
1. 1 <= matrix.length <= 300
2. 1 <= matrix[0].length <= 300
3. -1000 <= matrix[i] <= 1000
4. -10^8 <= target <= 10^8
方法一
** Solution Java **
** 1070ms, 34.58% **
** 45.9MB, 100.00% **
class Solution {
public int numSubmatrixSumTarget(int[][] matrix, int target) {
int res = 0, m = matrix.length, n = matrix[0].length;
for (int i = 0; i < m; ++i) {
for (int j = 1; j < n; ++j) {
matrix[i][j] += matrix[i][j - 1];
}
}
for (int i = 0; i < n; ++i) {
for (int j = i; j < n; ++j) {
Map<Integer, Integer> count = new HashMap<>();
count.put(0, 1);
int cur = 0;
for (int k = 0; k < m; ++k) {
cur += matrix[k][j] - (i > 0? matrix[k][i-1] : 0);
res += count.getOrDefault(cur - target, 0);
count.put(cur, count.getOrDefault(cur, 0) + 1);
}
}
}
return res;
}
}
** Solution Python3 **
** 7500ms, beats 32.94% **
** 19.8MB, beats 100.00% **
class Solution:
def numSubmatrixSumTarget(self, A, target):
m, n = len(A), len(A[0])
for row in A:
for i in range(n - 1):
row[i + 1] += row[i]
res = 0
for i in range(n):
for j in range(i, n):
c = collections.defaultdict(int)
cur, c[0] = 0, 1
for k in range(m):
cur += A[k][j] - (A[k][i - 1] if i > 0 else 0)
res += c[cur - target]
c[cur] += 1
return res
方法二
** Solution Java **
** 850ms, beats 81.16% **
** 48.7MB, beats 100.00% **
class Solution{
public int numSubmatrixSumTarget(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int[] temp = new int[m];
int ans = 0;
for (int left = 0; left < n; ++left) {
Arrays.fill(temp, 0);
for (int right = left; right < n; ++right) {
for (int i = 0; i < m; ++i)
temp[i] += matrix[i][right];
ans += subCount(temp, target);
}
}
return ans;
}
private int subCount(int[] temp, int target) {
Map<Integer, Integer> preSum = new HashMap<>();
int res = 0, curSum = 0;
for (int t : temp) {
curSum += t;
if (curSum == target)
++res;
if (preSum.containsKey(curSum - target))
res += preSum.get(curSum - target);
preSum.merge(curSum, 1, (a, b) -> a + b);
}
return res;
}
}