题目链接https://leetcode.cn/problems/coloring-a-border/
题目大意:给出一个二维矩阵grid,元素是int代表颜色。给出一个坐标row, col和一种颜色color,将这个坐标的连通分量的边界染成color的颜色。返回这个新的grid
思路:先DFS找连通分量,再遍历一遍将非边界的去掉就得到边界,再染色即可。当然写起来还是要注意一些小细节的。
一个二维vectorknown[]保存是否访问过,用于DFS;
一个二维vectorborder[]保存是否为边界;
一个注意点:如果某个格子就在grid的边界上且属于连通分量,那它一定属于连通分量的边界,因为连通分量不能再向外扩展了。
DFS过程
void DFS(vector<vector<int>>& grid, vector<vector<bool>>& known, vector<vector<bool>>& border, int origin, int row, int col) {
if (row < 0 || row >= grid.size() || col < 0 || col >= grid[0].size())
return;
if (known[row][col]) return;
known[row][col] = true;
if (grid[row][col] == origin) {
border[row][col] = true;
DFS(grid, known, border, origin, row, col+1);
DFS(grid, known, border, origin, row+1, col);
DFS(grid, known, border, origin, row, col-1);
DFS(grid, known, border, origin, row-1, col);
}
}
此时border[]内为true的是连通分量,接下来要去掉非边界的部分,遍历即可,四个方向都是相同颜色的话,它就是非边界。
for (int i = 1; i < m-1; i++) {
for (int j = 1; j < n-1; j++) {
if (border[i][j]) {
if (grid[i+1][j] == origin && grid[i][j+1] == origin
&& grid[i-1][j] == origin && grid[i][j-1] == origin) {
border[i][j] = false;
}
}
}
}
此时border内就只剩连通分量的边界了,遍历染色即可
完整代码
class Solution {
public:
void DFS(vector<vector<int>>& grid, vector<vector<bool>>& known, vector<vector<bool>>& border, int origin, int row, int col) {
if (row < 0 || row >= grid.size() || col < 0 || col >= grid[0].size())
return;
if (known[row][col]) return;
known[row][col] = true;
if (grid[row][col] == origin) {
border[row][col] = true;
DFS(grid, known, border, origin, row, col+1);
DFS(grid, known, border, origin, row+1, col);
DFS(grid, known, border, origin, row, col-1);
DFS(grid, known, border, origin, row-1, col);
}
}
vector<vector<int>> colorBorder(vector<vector<int>>& grid, int row, int col, int color) {
int origin = grid[row][col];
int m = grid.size(), n = grid[0].size();
vector<vector<bool>> known(m, vector<bool>(n, false));
vector<vector<bool>> border(m, vector<bool>(n, false));
DFS(grid, known, border, origin, row, col);
for (int i = 1; i < m-1; i++) {
for (int j = 1; j < n-1; j++) {
if (border[i][j]) {
if (grid[i+1][j] == origin && grid[i][j+1] == origin
&& grid[i-1][j] == origin && grid[i][j-1] == origin) {
border[i][j] = false;
}
}
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (border[i][j])
grid[i][j] = color;
}
}
return grid;
}
};