题意理解
给定一个矩阵,每个矩阵的方格放一个数字,现在求最大的连续相同数字面积。选择的数字不能是和0相连,也不能靠近四周,一定是被非0包围且和四周不连通
问题分析
深度递归遍历。dfs
使用队列实现dfs。
1. 这题用两次递归遍历,一次是标记无效的方格,靠边的和靠近0的。一次是找剩余面积。
2. 其中几个错误的点。对于边如果不是0不用标记相邻方格,对于是0要dfs标记相邻方格;每次dfs要重置面积;
3. 审题要清,几个错误都是审题没考虑到。
4. 遍历矩阵必须要dfs或bfs,中间每行代码出错都会不知道错哪,模板要记得了,
5. 关于调试,要增加批量打日志,现在力扣限制日志行数,所以要用vscode支持输入,用本地方便跑数。
其他
本题做了整整一天,从早上7点半道晚上6点。奔溃了。
刷题准备动作必须要有了,先熟悉基本算法,不然没法刷题。尤其是我这种没有办法天天刷题的,很容易忘记基本知识。打击自信心。
链接
https://leetcode-cn.com/problems/YesdPw/
class Solution {
public:
vector<vector<int>> env={{-1,0},{1,0},{0,-1},{0,1}};
int largestArea(vector<string>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> visited(m, vector<int>(n,0));
int area = 0;
//cout << " process edge" << endl;
for (int i = 0; i < m; i ++) {
for(int j = 0; j < n; j ++) {
if (visited[i][j] == 1) continue;
if (grid[i][j] == '0') {
dfs(grid, visited, i, j, m, n, area);
}
else {
if (i == 0 || j == 0 || i == m-1 || j == n-1) {
dfs(grid, visited, i, j, m, n, area);
}
}
}
}
for(int i = 0; i < m; i ++) {
for (int j = 0; j < n; j ++) {
cout << visited[i][j];
}
cout << endl;
}
int max_area = 0;
//cout << " process area" << endl;
for (int i = 0; i < m; i ++) {
for (int j = 0; j < n; j ++) {
//cout << "calc area " << i << '\t' << j << endl;
if (visited[i][j] == 1) continue;
area = 0;
dfs(grid, visited, i, j, m, n, area);
if (area > max_area) max_area = area;
//cout << "max area" << max_area << "area " << area << endl;
}
}
return max_area;
}
void dfs(vector<string>& grid, vector<vector<int>>& visited, int i, int j, int m, int n, int& area) {
//cout << "dfs:" << i << '\t' << j << endl;
queue<pair<int, int>> que;
que.push(make_pair(i, j));
while(!que.empty()) {
int cur_i = que.front().first;
int cur_j = que.front().second;
//if (cur_i == 1 && cur_j == 8) cout << "next que elment " << cur_i << '\t' << cur_j << endl;
que.pop();
visited[cur_i][cur_j] = 1;
area++;
//cout << "inner area " << area << endl;
for(int i = 0; i < 4; i ++) {
int next_i = cur_i + env[i][0];
int next_j = cur_j + env[i][1];
//if (cur_i == 1 && cur_j == 8) cout << "next pos " << next_i << '\t' << next_j << endl;
if (next_i < 0 || next_i >= m || next_j < 0 || next_j >= n) {
//if (cur_i == 1 && cur_j == 8) cout << "overflow" << endl;
continue;
}
if (visited[next_i][next_j] == 1) {
//if (cur_i == 1 && cur_j == 8) cout << "visited" << endl;
continue;
}
// 与走廊相邻,标记已访问,不入队列
//if (grid[cur_i][cur_j] == '0') {
// visited[next_i][next_j] = 1;
// }
//相等入队列,需要深入遍历
if (grid[cur_i][cur_j] == '0' || grid[cur_i][cur_j] == grid[next_i][next_j]) {
visited[next_i][next_j] = 1;
que.push(make_pair(next_i, next_j));
//if (cur_i == 1 && cur_j == 8) cout << "push queue " << next_i << '\t' << next_j << endl;
}
}
}
}
};