枚举子矩阵的上下边界,并计算出该边界内每列的元素和,则原问题转换成了如下一维问题:
给定一个整数数组和一个整数 target,计算该数组中子数组和等于 target 的子数组个数。
其中往前缀和出现次数的列表中加1 和 查询pre-k出现的次数 的顺序很关键,一定要先查询再加1
如果先加1再查询,当k=0时, 统计的pre-k出现的次数会正常多一次,自己减了一次自己
class Solution:
def numSubmatrixSumTarget(self, matrix: List[List[int]], target: int) -> int:
def subarraySum(nums: List[int], k: int) -> int:
mp = Counter([0])
count = pre = 0
for x in nums:
pre += x
if pre - k in mp:
count += mp[pre - k]
mp[pre] += 1
return count
m, n = len(matrix), len(matrix[0])
ans = 0
# 枚举上边界
for i in range(m):
total = [0] * n
# 枚举下边界
for j in range(i, m):
for c in range(n):
# 更新每列的元素和
total[c] += matrix[j][c]
ans += subarraySum(total, target)
return ans