1034. Coloring A Border
Given a 2-dimensional grid
of integers, each value in the grid represents the color of the grid square at that location.
Two squares belong to the same connected component if and only if they have the same color and are next to each other in any of the 4 directions.
The border of a connected component is all the squares in the connected component that are either 4-directionally adjacent to a square not in the component, or on the boundary of the grid (the first or last row or column).
Given a square at location (r0, c0)
in the grid and a color
, color the border of the connected component of that square with the given color
, and return the final grid
.
Example 1:
Input: grid = [[1,1],[1,2]], r0 = 0, c0 = 0, color = 3
Output: [[3, 3], [3, 2]]
Example 2:
Input: grid = [[1,2,2],[2,3,2]], r0 = 0, c0 = 1, color = 3
Output: [[1, 3, 3], [2, 3, 3]]
Example 3:
Input: grid = [[1,1,1],[1,1,1],[1,1,1]], r0 = 1, c0 = 1, color = 2
Output: [[2, 2, 2], [2, 1, 2], [2, 2, 2]]
Note:
1 <= grid.length <= 50
1 <= grid[0].length <= 50
1 <= grid[i][j] <= 1000
0 <= r0 < grid.length
0 <= c0 < grid[0].length
1 <= color <= 1000
以上为题目的描述, 本来以为又是一BFS的题目就简单看了一下题目就开写,结果提交之后发现答案不对,又仔细看了一边题目, 发现了其实是自己压根就没看明白题, The border of a connected component is all the squares in the connected component that are either 4-directionally adjacent to a square not in the component, or on the boundary of the grid (the first or last row or column). 这里说的是connected component中边界定义, 一种是四个方向任何一个方向连接着非本connected component中格子, 简单说就是有一个方向连接着不同颜色的格子, 另一种是直接到达grid的边界。好了,题目弄清了,下面开干, 其实这个问题就是在普通的BFS问题上添加了另一个染色条件, 就是只有connected component的边界格子可以染色, 处于中心的格子不能被染色。简单的应对办法就是,添加中间类型, 因为1 <= color <= 1000, 我本来是拿1001这个值作为标记,记录已经走过的格子, 但是如果单用这一个值就会有问题, 就是我们标记完整个grid后,我们还需要再去区分一遍我们标记的这些1001的格子是边界的还是中心的。于是我就直接添加了另一个值1002作为标记值, 中心的格子标记为1001, 边界的格子标记为1002, 标记完成后我们只需要再便利一边grid, 把1001的各自复原成原来的值, 1002的标记成目标颜色就可以了。以下是代码(Rust):
impl Solution {
pub fn color_border(mut grid: Vec<Vec<i32>>, r0: i32, c0: i32, color: i32) -> Vec<Vec<i32>> {
// 起始格子的原始颜色, 用于后期恢复处于中间位置的格子时使用
let ori_color = grid[r0 as usize][c0 as usize];
let mut queue: Vec<(usize, usize)> = vec![(r0 as usize, c0 as usize)];
while !queue.is_empty() {
for _ in 0..queue.len() {
let (row, col) = queue.remove(0);
// 相邻的处于同一connected component的格子数量
let mut count = 0;
if row > 0 {
// 如果是同一颜色的证明还没有走过, 推入队列, 计数加1
if grid[row - 1][col] == ori_color {
queue.push((row - 1, col));
count += 1;
}
// 如果是已经走过的格子, 则只增加计数就好
if grid[row - 1][col] == 1001 || grid[row - 1][col] == 1002 {
count += 1;
}
}
if row < grid.len() - 1 {
if grid[row + 1][col] == ori_color {
queue.push((row + 1, col));
count += 1;
}
if grid[row + 1][col] == 1001 || grid[row + 1][col] == 1002 {
count += 1;
}
}
if col > 0 {
if grid[row][col - 1] == ori_color {
queue.push((row, col - 1));
count += 1;
}
if grid[row][col - 1] == 1001 || grid[row][col - 1] == 1002 {
count += 1;
}
}
if col < grid[0].len() - 1 {
if grid[row][col + 1] == ori_color {
queue.push((row, col + 1));
count += 1;
}
if grid[row][col + 1] == 1001 || grid[row][col + 1] == 1002 {
count += 1
}
}
if count < 4 {
grid[row][col] = 1002;
} else {
grid[row][col] = 1001;
}
}
}
// 遍历grid, 将值为1001的格子(处于中心的格子)填充回原来的颜色, 将值为1002的格子填充为目标颜色
grid.iter_mut().for_each(|row| {
row.iter_mut().for_each(|v| {
if v == &1001 {
*v = ori_color;
} else if v == &1002 {
*v = color;
}
});
});
grid
}
}