LeetCode 1074 元素和为目标值的子矩阵数量[动态规划 前缀和 暴力] HERODING的LeetCode之路
Posted HERODING23
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1074 元素和为目标值的子矩阵数量[动态规划 前缀和 暴力] HERODING的LeetCode之路相关的知识,希望对你有一定的参考价值。
解题思路:
首先我们得把该数组的前缀和给表示出来,就是i行和j列组合成的矩阵的和是由i-1、j列,i-1、j列,i-1、j-1列的值组成,得到我们想要的前缀和之后,首先用暴力去解决尝试一波,就是对每个i,j分割的矩阵,遍历每一个子矩阵,时间复杂度达到了O(n^2· m^2),代码如下:
class Solution {
public:
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
int m = matrix.size(), n = matrix[0].size();
int s[m + 1][n + 1];
memset(s, 0, sizeof s);
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + matrix[i - 1][j - 1];
int ans = 0;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= i; k++)
for (int l = 1; l <= j; l++) {
int sum = s[i][j] - s[i][l - 1] - s[k - 1][j] + s[k - 1][l - 1];
if (sum == target)
ans++;
}
return ans;
}
};
当然最好的情况还是优化成O(n^2 · m)的情况,这需要用到前缀和和哈希表的组合,这种思想在我写的这个题解中有着详细的解释,并且一看就能懂,那么在本题中直接套用该方法即可,代码如下:
class Solution {
public:
int countTarget(vector<int>& num, int target) {
unordered_map<int, int> count;
int res = 0, sum = 0;
count[0] = 1;
for(auto& n : num) {
sum += n;
if(count.find(sum - target) != count.end()) {
res += count[sum - target];
}
count[sum] ++;
}
return res;
}
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
// 如果为空
if(matrix.size() == 0) {
return 0;
}
int m = matrix.size(), n = matrix[0].size();
int ans = 0;
for(int i = 0; i < m; i ++) {// 上界
vector<int> sum(n, 0);
for(int j = i; j < m; j ++) {// 从上界往下
for(int k = 0; k < n; k ++) {// 遍历每一列
sum[k] += matrix[j][k];
}
ans += countTarget(sum, target);// 加上统计的数目
}
}
return ans;
}
};
/*作者:heroding
链接:https://leetcode-cn.com/problems/number-of-submatrices-that-sum-to-target/solution/cha-xi-biao-qian-zhui-he-by-heroding-s3v9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/
以上是关于LeetCode 1074 元素和为目标值的子矩阵数量[动态规划 前缀和 暴力] HERODING的LeetCode之路的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 1074 元素和为目标值的子矩阵数量[动态规划 前缀和 暴力] HERODING的LeetCode之路