前言
欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
今天是六月集训第十一天:矩阵🔥🔥🔥🔥
一、练习题目
二、算法思路
- 1、面试题 01.08. 零矩阵:三重for循环暴力过。🔥🔥
- 2、73. 矩阵置零:同上。🔥🔥
- 3、1727. 重新排列后的最大子矩阵:这题涉及的蛮多的,首先把二维降到一维,排序后贪心的去算直方图的面积。🔥🔥🔥🔥🔥
- 4、1034. 边界着色:最近事情有点多,稍微难的我放一下,会来补写。🔥🔥🔥🔥🔥
三、源码剖析
// 面试题 01.08. 零矩阵
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
vector<vector<int>> tmp(matrix); //(1)
int n = matrix.size();
int m = matrix[0].size();
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if(tmp[i][j] == 0) { //(2)
for(int k = 0; k < n; ++k) {
matrix[k][j] = 0;
}
for(int k = 0; k < m; ++k) {
matrix[i][k] = 0;
}
}
}
}
}
};
- 1、拷贝一个新的矩阵;
- 2、每次判断一个新的矩阵对应的位置是否为零,如果是则将原先的矩阵的行和列都置为零。
// 73. 矩阵置零
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
vector<vector<int>> tmp(matrix);
int n = matrix.size();
int m = matrix[0].size();
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if(tmp[i][j] == 0) {
for(int k = 0; k < n; ++k) {
matrix[k][j] = 0;
}
for(int k = 0; k < m; ++k) {
matrix[i][k] = 0;
}
}
}
}
}
};
- 1、同上。
// 1727. 重新排列后的最大子矩阵
class Solution {
public:
int largestSubmatrix(vector<vector<int>>& matrix) {
int m = matrix.size();
int n = matrix[0].size();
int vline[100010], tvline[100010];
int ans = INT_MIN;
memset(vline,0, sizeof(vline));
for(int i = 0; i < m; ++i) {
for(int j = 0; j < n; ++j) {
if(matrix[i][j] == 0) {
vline[j] = 0;
} else {
vline[j] = vline[j] + 1;
}
} //(1)
for(int j = 0; j < n; ++j) {
tvline[j] = vline[j];
}
sort(tvline, tvline + n); //(2)
for(int j = 0; j < n; ++j) {
ans = max(ans, tvline[j] * (n - j));
}
}
return ans;
}
};
- 1、预处理每一行为地平线,向上生长得到的最大高度
- 2、排序后贪心的求直方图的面积;(参考了题解)
// 1034. 边界着色
- 1、