给出矩阵 matrix 和目标值 target,返回元素总和等于目标值的非空子矩阵的数量。
子矩阵 x1, y1, x2, y2 是满足 x1 <= x <= x2 且 y1 <= y <= y2 的所有单元 matrix[x][y] 的集合。
如果 (x1, y1, x2, y2) 和 (x1’, y1’, x2’, y2’) 两个子矩阵中部分座标不同(如:x1 != x1’),那么这两个子矩阵也不同。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-submatrices-that-sum-to-target
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
——————————
解题思路:
(1)对于一个rows行,cols列的矩阵,计算每一行的前缀和,得到一个基于行的前缀和矩阵。
(2)基于列对前缀和矩阵进行划分,对于有cols列的前缀和矩阵,不同列的组合有cols*(cols-1)种,将不同列的值累加到同一列中,这样就从二维矩阵变为一维的矩阵,然后利用字典的方法来统计不同子矩阵的数量。
class Solution:
def numSubmatrixSumTarget(self, matrix: List[List[int]], target: int) -> int:
# 计算行和列
rows,cols = len(matrix),len(matrix[0])
# nums是前缀和矩阵
nums = [[0 for _ in range(cols)] for _ in range(rows)]
for i in range(rows):
nums[i][0] = matrix[i][0]
for j in range(1,cols):
nums[i][j] = nums[i][j-1] + matrix[i][j]
# ans是保存符合要求的子矩阵的数量
ans = 0
# sum用于保存将多列前缀和累计为单列前缀和的矩阵
sums = [0 for _ in range(rows)]
# 计算不同列之间组成的前缀和组合
for i in range(cols):
for j in range(i,cols):
if i == 0:
for k in range(rows):
sums[k] = nums[k][j]
else:
for k in range(rows):
sums[k] = nums[k][j] - nums[k][i-1]
# 将多列前缀和变为单列前缀和之后执行下面操作
dicts = dict()
# dicts[0] = 1很重要
dicts[0] = 1
num = 0 # 用于保存前n个值之和
for n in sums:
num += n
if num-target in dicts.keys():
ans += dicts[num-target]
dicts.setdefault(num,0)
dicts[num] += 1
return ans