这里写自定义目录标题
- 304.二维区域和检索-矩阵不可变
- 1314.矩阵区域和
- 1074.元素和为目标值的子矩阵数量
- 363.矩形区域不超过K的最大数值和
- 面试题17.24.最大子矩阵
- 1292.元素和小于等于阈值的正方形的最大边长
- 1738.找出第K大的异或坐标值
- 2245.转角路径的乘积中最多能有几个尾随零
304.二维区域和检索-矩阵不可变
class NumMatrix {
public:
vector<vector<int>> pre;
vector<vector<int>> nums;
NumMatrix(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
pre.resize(m+1,vector<int>(n+1));
for(int i{};i<m;++i){
for(int j{};j<n;++j){
pre[i+1][j+1] = pre[i][j+1] + pre[i+1][j] - pre[i][j] + matrix[i][j];
}
}
nums = matrix;
}
int sumRegion(int row1, int col1, int row2, int col2) {
return pre[row2+1][col2+1] - pre[row1][col2+1] - pre[row2+1][col1] + pre[row1][col1] ;
}
};
1314.矩阵区域和
class Solution {
public:
vector<vector<int>> nums;
vector<vector<int>> pre;
int get(int m, int n, int x, int y) {
x = max(min(x, m), 0);
y = max(min(y, n), 0);
return pre[x][y];
}
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
nums = mat;
int m = mat.size();
int n = mat[0].size();
pre.resize(m+1,vector<int>(n+1));
for(int i{};i<m;++i){
for(int j{};j<n;++j){
pre[i+1][j+1] = pre[i][j+1] + pre[i+1][j] - pre[i][j] + mat[i][j];
}
}
vector<vector<int>> result(m,vector<int>(n));
for(int i{};i<m;++i){
for(int j{};j<n;++j){
result[i][j] =get(m, n, i + k + 1, j + k + 1) - get(m, n, i - k, j + k + 1) - get(m, n, i + k + 1, j - k) + get(m, n, i - k, j - k);
}
}
return result;
}
};
1074.元素和为目标值的子矩阵数量
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> mp;
mp[0] = 1;
int count = 0;
int n = nums.size();
vector<int> pre(n+1);
for(int i{};i<n;++i){
pre[i+1] = pre[i] + nums[i];
if (mp.find(pre[i+1]- k) != mp.end()) {
count += mp[pre[i+1]- k];
}
mp[pre[i+1]]++;
}
return count;
}
int numSubmatrixSumTarget(vector<vector<int>>& matrix, int target) {
int m = matrix.size();
int n = matrix[0].size();
int result{};
for(int i{};i<m;++i){
vector<int> sums(n);
for(int j = i;j<m;++j){
for(int c{};c<n;++c){
sums[c] += matrix[j][c];
}
result += subarraySum(sums, target);
}
}
return result;
}
};
363.矩形区域不超过K的最大数值和
class Solution {
public:
int maxSumSubmatrix(vector<vector<int>>& matrix, int k) {
int m = matrix.size();
int n = matrix[0].size();
int result{ INT_MIN};
for(int i{};i<m;++i){
vector<int> sums(n);
for(int j = i;j<m;++j){
for(int c{};c<n;++c){
sums[c] += matrix[j][c];
}
set<int> sumSet{0};
int pre{};
for(int &num : sums){
pre += num;
auto lb = sumSet.lower_bound(pre-k);
if(lb != sumSet.end()){
result = max(result,pre-*lb);
}
sumSet.insert(pre);
}
}
}
return result;
}
};
面试题17.24.最大子矩阵
class Solution {
public:
vector<int> getMaxMatrix(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
int result{ INT_MIN};
vector<int> resultV;
for(int top{};top<m;++top){
vector<int> sums(n);
for(int bottom = top;bottom<m;++bottom){
for(int c{};c<n;++c){
sums[c] += matrix[bottom][c];
}
int left{};
int tempValue{};
for(int right{};right < n;++right){
tempValue += sums[right];
if(tempValue > result){
resultV = {top,left,bottom,right};
result = tempValue;
}
if(tempValue < 0){
left = right +1;
tempValue = 0;
}
}
}
}
return resultV;
}
};
1292.元素和小于等于阈值的正方形的最大边长
class Solution {
public:
vector<vector<int>> nums;
vector<vector<int>> pre;
int maxSideLength(vector<vector<int>>& mat, int threshold) {
nums = mat;
int m = mat.size();
int n = mat[0].size();
pre.resize(m+1,vector<int>(n+1));
for(int i{};i<m;++i){
for(int j{};j<n;++j){
pre[i+1][j+1] = pre[i][j+1] + pre[i+1][j] - pre[i][j] + mat[i][j];
}
}
int result{};
for(int i{};i<m;++i){
for(int j{};j<n;++j){
for (int k=0;(k+i<m) && (k+j<n);k++){
long long sum=pre[i+k+1][j+k+1]-pre[i+k+1][j]-pre[i][j+k+1]+pre[i][j];
if (sum<=threshold) {
result=max(result,k+1);
}
}
}
}
return result;
}
};
1738.找出第K大的异或坐标值
class Solution {
public:
2245.转角路径的乘积中最多能有几个尾随零
int c25[1001][2];
int init = []() {
for (int i = 2; i <= 1000; ++i) {
if (i % 2 == 0) c25[i][0] = c25[i / 2][0] + 1;
if (i % 5 == 0) c25[i][1] = c25[i / 5][1] + 1;
}
return 0;
}();
class Solution {
public:
int maxTrailingZeros(vector<vector<int>> &grid) {
int m = grid.size(), n = grid[0].size(), ans = 0;
int s[m][n + 1][2];
for (int i = 0; i < m; ++i) {
s[i][0][0] = s[i][0][1] = 0;
for (int j = 0; j < n; ++j) {
s[i][j + 1][0] = s[i][j][0] + c25[grid[i][j]][0];
s[i][j + 1][1] = s[i][j][1] + c25[grid[i][j]][1];
}
}
for (int j = 0; j < n; ++j) {
for (int i = 0, s2 = 0, s5 = 0; i < m; ++i) {
s2 += c25[grid[i][j]][0];
s5 += c25[grid[i][j]][1];
ans = max(ans, max(min(s2 + s[i][j][0], s5 + s[i][j][1]),
min(s2 + s[i][n][0] - s[i][j + 1][0], s5 + s[i][n][1] - s[i][j + 1][1])));
}
for (int i = m - 1, s2 = 0, s5 = 0; i >= 0; --i) {
s2 += c25[grid[i][j]][0];
s5 += c25[grid[i][j]][1];
ans = max(ans, max(min(s2 + s[i][j][0], s5 + s[i][j][1]),
min(s2 + s[i][n][0] - s[i][j + 1][0], s5 + s[i][n][1] - s[i][j + 1][1])));
}
}
return ans;
}
};