LeetCode每日一题(1034. Coloring A Border)

给定一个二维整数网格,其中每个单元格都有颜色。两个单元格属于同一连通组件,如果它们颜色相同且相邻(上下左右)。题目要求给定位置的单元格及其连通组件的边界涂上指定颜色。文章解析了题目难点,并提供了使用BFS解决此问题的Rust代码实现。
摘要由CSDN通过智能技术生成

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. 1 <= grid.length <= 50
  2. 1 <= grid[0].length <= 50
  3. 1 <= grid[i][j] <= 1000
  4. 0 <= r0 < grid.length
  5. 0 <= c0 < grid[0].length
  6. 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
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值