题目链接

二维前缀和暴力思路,时间复杂度
O
(
n
2
×
m
2
)
O(n^2\times m^2)
O(n2×m2)
class Solution {
public:
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
int s[110][110];
int n = matrix.size(), m = matrix[0].size();
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
s[i+1][j+1] = matrix[i][j] + s[i+1][j] + s[i][j+1] - s[i][j];
int res = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
for(int x = 1; x <= i; x++)
{
for(int y = 1; y <= j; y++)
{
int t = s[i][j] - s[x-1][j] - s[i][y-1] + s[x-1][y-1];
if(t == target) res++;
}
}
}
}
return res;
}
};
哈希表+前缀和线性优化,最优的一个做法的时间复杂度 O ( m i n ( n , m ) 2 × m a x ( n , m ) ) O(min(n,m)^2\times max(n,m)) O(min(n,m)2×max(n,m))
class Solution {
public:
int solve(vector<int>& num, int target)
{
int cnt = 0, pre = 0, len = num.size();
unordered_map<int, int> hash;
hash[0] = 1;
for(int i = 0; i < len; i++)
{
pre += num[i];
if(hash.find(pre - target) != hash.end())
cnt += hash[pre-target];
hash[pre]++;
}
return cnt;
}
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
int n = matrix.size(), m = matrix[0].size();
int x = min(n,m), y = max(n,m);
int s[x+1][y+1], a[x+1][y+1];
if(n > m)
{
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
a[j][i] = matrix[i][j];
}
else{
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
a[i][j] = matrix[i][j];
}
int res = 0;
for(int i = 0; i < x; i++)
{
vector<int> sum(y);
for(int j = i; j < x; j++)
{
for(int k = 0; k < y; k++)
sum[k] += a[j][k];
res += solve(sum, target);
}
}
return res;
}
};
这篇博客介绍了两种解决二维矩阵中子矩阵和为目标值的计数问题的方法。第一种是暴力求解,使用双重循环和前缀和,时间复杂度为O(n²×m²)。第二种方法利用哈希表和前缀和进行线性优化,将时间复杂度降低到O(min(n,m)²×max(n,m))。博客详细阐述了这两种算法的实现细节和优化思路。
668

被折叠的 条评论
为什么被折叠?



