给你一个大小为 m x n 的整数矩阵 grid ,表示一个网格。另给你三个整数 row、col 和 color 。网格中的每个值表示该位置处的网格块的颜色。
当两个网格块的颜色相同,而且在四个方向中任意一个方向上相邻时,它们属于同一 连通分量 。
连通分量的边界 是指连通分量中的所有与不在分量中的网格块相邻(四个方向上)的所有网格块,或者在网格的边界上(第一行/列或最后一行/列)的所有网格块。
请你使用指定颜色 color 为所有包含网格块 grid[row][col] 的 连通分量的边界 进行着色,并返回最终的网格 grid 。
示例 1:
输入:grid = [[1,1],[1,2]], row = 0, col = 0, color = 3
输出:[[3,3],[3,2]]
示例 2:
输入:grid = [[1,2,2],[2,3,2]], row = 0, col = 1, color = 3
输出:[[1,3,3],[2,3,3]]
示例 3:
输入:grid = [[1,1,1],[1,1,1],[1,1,1]], row = 1, col = 1, color = 2
输出:[[2,2,2],[2,1,2],[2,2,2]]
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 50
1 <= grid[i][j], color <= 1000
0 <= row < m
0 <= col < n
题解:
我们先必须找到这个grid[row,col]这个连通块,然后找出连通块的边界,这儿的边界是指四周(上下左右)没有连通块包围,我们可以用一个cnt计数,当cnt为4代表被包围,就不是边界,否则就是边界。
细节:
我们可以先开一个数组来更新值,因为可以根据数组值是不是0来判断是否更新过,进行去重
bfs
class Solution {
public int[][] colorBorder(int[][] grid, int row, int col, int color) {
Queue<int[]> queue = new LinkedList<>();
int n = grid.length, m = grid[0].length;
int[] d = new int[]{-1,0,1,0,-1}; //坐标数组
queue.add(new int[]{row,col});
int c = grid[row][col]; //c记录初始颜色
int[][] res = new int[n][m];
while(!queue.isEmpty()){
int[] q = queue.poll();
int x = q[0], y = q[1];
int cnt = 0; //cnt记录当前坐标是不是边界(如果cnt为4代表不是边界)
//遍历四个方向
for(int i = 0; i < 4; ++i){
int dx = x + d[i], dy = y + d[i+1];
//当坐标出界或者不是同一个连通块(不等于初始颜色c)跳过
if(dx < 0 || dx >= n || dy < 0 || dy >= m
|| grid[dx][dy] != c) continue;
if(grid[dx][dy] == c) cnt++; //相等就cnt++
if(res[x][y] != 0) continue; //如果不为0代表已经遍历过
queue.add(new int[]{dx,dy});
}
res[x][y] = cnt == 4 ? grid[x][y] : color;
}
//第二次遍历
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
if(res[i][j] == 0)
res[i][j] = grid[i][j];
return res;
}
}
dfs
class Solution {
int[][] grid,res;
int color;
int n,m;
int[] d = new int[]{-1,0,1,0,-1}; //坐标变换数组
int c; //记录初始连通块的颜色
public int[][] colorBorder(int[][] grid, int row, int col, int color) {
this.grid = grid;
this.color = color;
c = grid[row][col];
n = grid.length; m = grid[0].length;
res = new int[n][m];
dfs(row,col);
//二次遍历
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j)
if(res[i][j] == 0) res[i][j] = grid[i][j];
return res;
}
public void dfs(int row, int col){
int cnt = 0; //记录是不是连通块边界(cnt != 4)
for(int i = 0; i < 4; ++i){
int dx = row + d[i], dy = col + d[i+1];
if(dx < 0 || dx >= n || dy < 0 || dy >= m) continue;
if(grid[dx][dy] != c) continue;
else cnt++;
if(res[dx][dy] != 0) continue;
//防止重复搜索
res[dx][dy] = -1;
dfs(dx,dy);
}
res[row][col] = cnt == 4 ? grid[row][col] : color;
}
}