1034.边界着色
题目描述
给你一个大小为 m x n 的整数矩阵 grid ,表示一个网格。另给你三个整数 row、col 和 color 。网格中的每个值表示该位置处的网格块的颜色。
两个网格块属于同一 连通分量 需满足下述全部条件:
两个网格块颜色相同
在上、下、左、右任意一个方向上相邻
连通分量的边界 是指连通分量中满足下述条件之一的所有网格块:
在上、下、左、右任意一个方向上与不属于同一连通分量的网格块相邻
在网格的边界上(第一行/列或最后一行/列)
请你使用指定颜色 color 为所有包含网格块 grid[row][col] 的 连通分量的边界 进行着色,并返回最终的网格 grid 。
示例一:
输入:grid = [[1,1],[1,2]], row = 0, col = 0, color = 3
输出:[[3,3],[3,2]]
示例二:
输入:grid = [[1,2,2],[2,3,2]], row = 0, col = 1, color = 3
输出:[[1,3,3],[2,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]]
用通俗易懂的语言重新描述题目。。。
这道题真的光题目我就看了半小时。。。我一度怀疑这是语文题
1.连通区域:类似昨天的岛屿问题中的岛屿,有兴趣的小伙伴可以翻阅上一篇
岛屿问题题解
2.连通区域的边界:点本身就在数组的边缘,或者其上下左右四个点有一个不属于连通区域,我们要染色的目标就是这些边界点。
解题思路
这道题与岛屿问题十分类似,核心思想都是一样的,只不过我们找到连通区域的点后加一步判断其是不是连通区域的边界就可以了。
举个栗子
输入:
[1,2,1,2,1,2]
[2,2,2,2,1,2]
[1,2,2,2,1,2]
1
3
1
连通区域:
连通区域的边界:
代码实现(java)
class Solution {
//标记原始的颜色
int precolor;
//标记是否被访问过
boolean[][] flag ;
public int[][] colorBorder(int[][] grid, int row, int col, int color) {
precolor = grid[row][col];
flag = new boolean[grid.length][grid[0].length];
dfs(grid,row,col,color,precolor,flag);
return grid;
}
public void dfs(int[][] grid, int row, int col, int color,int precolor,boolean[][] flag){
//退出条件
if(row<0||col<0||row>=grid.length||col>=grid[0].length||grid[row][col]!=precolor||flag[row][col])
return;
//程序能执行到这里说明找到的点和目标点属于同一个连通分量,且没有越界
//判断是否是位于数组边界的点,是的话就进行染色
if(flag[row][col]==false&&(row==0||row==grid.length-1||col==0||col==grid[0].length-1))
grid[row][col] = color;
//若这个点上下左右有一个点不属于该连通区域,该点就是连通区域的边界点
if(isTrue(grid,row,col+1)||isTrue(grid,row,col-1)||isTrue(grid,row-1,col)||isTrue(grid,row+1,col))
grid[row][col] = color;
//该点标记为已访问过
flag[row][col]=true;
//继续进行深搜
dfs(grid,row-1,col,color,precolor,flag);
dfs(grid,row+1,col,color,precolor,flag);
dfs(grid,row,col-1,color,precolor,flag);
dfs(grid,row,col+1,color,precolor,flag);
}
public boolean isTrue (int[][] grid,int i,int j){
//第一种情况,越界,这一步的目的是防止报错。
if(i<0||i>=grid.length||j<0||j>=grid[0].length)
return false;
//未被访问过且,颜色与初始点的颜色不一样
if(grid[i][j]!=precolor&&!flag[i][j])
return true;
//被访问过或者颜色与初始点一样
return false;
}
}