LeetCode 1074. 元素和为目标值的子矩阵数量(map,前缀和)
Posted live4m
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1074. 元素和为目标值的子矩阵数量(map,前缀和)相关的知识,希望对你有一定的参考价值。
题意:
给出矩阵 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'),那么这两个子矩阵也不同。
数据范围:
1 <= matrix.length <= 100
1 <= matrix[0].length <= 100
-1000 <= matrix[i] <= 1000
-10^8 <= target <= 10^8
解法:
令s(i,j)表示第j列前i个元素的前缀和。
枚举两条横线作为矩阵的上下边界L和R,
然后就是在上下边界的前提下计算权值和满足条件的左右边界,
显然中间每一列的值d[k]=sum(R,k)-sum(L-1,k).
问题变为d[]有多少个满足和为target的区间,
预处理签注和,枚举sum[r],同时map维护左边每种sum[l]的数量
对于每个r,ans+=mp[sum[r]-target]即可。
复杂度O(n^3*log)
code:
/*
* @lc app=leetcode.cn id=1074 lang=cpp
*
* [1074] 元素和为目标值的子矩阵数量
*/
// @lc code=start
#define ll long long
const int maxm=333;
ll s[maxm][maxm];
ll d[maxm];
class Solution {
public:
int numSubmatrixSumTarget(vector<vector<int>>& a, int p) {
memset(s,0,sizeof s);
memset(d,0,sizeof d);
int n=a.size(),m=a[0].size();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
s[i][j]=s[i-1][j]+a[i-1][j-1];
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
for(int k=1;k<=m;k++){
d[k]=s[j][k]-s[i-1][k];
d[k]+=d[k-1];
}
unordered_map<int,int>mp;
mp[0]=1;
for(int k=1;k<=m;k++){
ans+=mp[d[k]-p];
mp[d[k]]++;
}
}
}
return ans;
}
};
// @lc code=end
以上是关于LeetCode 1074. 元素和为目标值的子矩阵数量(map,前缀和)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 1074. 元素和为目标值的子矩阵数量(map,前缀和)
LeetCode 1074 元素和为目标值的子矩阵数量[动态规划 前缀和 暴力] HERODING的LeetCode之路