leetcode
leetcode 951 ~ 1000
边界着色

边界着色

难度:

标签:

题目描述

代码结果

运行时间: 26 ms, 内存: 16.2 MB


/*
题目思路:
1. 获取初始位置的颜色,检查如果初始颜色和目标颜色相同,直接返回。
2. 使用广度优先搜索(BFS)找到与初始位置颜色相同的连通分量。
3. 使用Java Stream API来遍历和操作数组数据。
*/
import java.util.*;
import java.util.stream.*;

public class Solution {
    private int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    public int[][] colorBorder(int[][] grid, int row, int col, int color) {
        int originalColor = grid[row][col];
        if (originalColor == color) return grid;

        boolean[][] visited = new boolean[grid.length][grid[0].length];
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[]{row, col});
        visited[row][col] = true;
        List<int[]> borderCells = new ArrayList<>();

        while (!queue.isEmpty()) {
            int[] cell = queue.poll();
            int r = cell[0], c = cell[1];
            boolean isBorder = false;
            for (int[] dir : directions) {
                int newRow = r + dir[0];
                int newCol = c + dir[1];
                if (newRow < 0 || newRow >= grid.length || newCol < 0 || newCol >= grid[0].length || grid[newRow][newCol] != originalColor) {
                    isBorder = true;
                } else if (!visited[newRow][newCol]) {
                    queue.add(new int[]{newRow, newCol});
                    visited[newRow][newCol] = true;
                }
            }
            if (isBorder) borderCells.add(new int[]{r, c});
        }

        borderCells.stream().forEach(cell -> grid[cell[0]][cell[1]] = color);

        return grid;
    }
}

解释

方法:

这个题解使用了广度优先搜索(BFS)来找出所有与起始网格块相连的网格块,并记录下是否位于边界或相邻于不同颜色的网格块。首先,初始化一个队列和一个访问集合,用于记录已访问的网格块。将起点加入队列和访问集合。然后,从队列中取出网格块,检查它是否位于边界,或者它的任一相邻网格块是否不属于同一连通分量(颜色不同或者已经越界)。如果满足这些条件,就将该网格块标记为边界,并将其颜色改为指定颜色。否则,如果相邻网格块属于同一连通分量且未被访问过,将其加入队列继续搜索。这个过程重复,直到队列为空,最后返回修改后的网格。

时间复杂度:

O(m * n)

空间复杂度:

O(m * n)

代码细节讲解

🦆
在BFS算法中,为什么要使用一个队列和一个访问集合来记录已访问的网格块?
在广度优先搜索(BFS)中,队列用于维护待探索的节点顺序,确保算法按层次逐级处理节点,从而实现广度优先的搜索模式。访问集合则用于记录已经访问过的节点,防止重复处理同一个节点,这可以避免无限循环和不必要的计算重复。在处理图或网格这样的数据结构时,这种机制尤为重要,因为图中可能存在循环连接,而网格中网格块可能从多个方向被访问。
🦆
题解中提到,如果网格块位于物理边界或者与不同颜色的网格块相邻,则将其视为连通分量的边界。这种判断方法是否会错误地将内部但接触到不同颜色网格块的网格也标记为边界?
是的,这种判断方法确实会将接触到不同颜色网格块的内部网格块标记为边界。这是按照题目要求设计的,因为题目目的是着色所有位于边界的网格块,其中边界的定义包括物理边界和颜色边界。颜色边界指的是与其他颜色网格块接触的网格块,即使这些网格块位于内部。这样的设计确保了所有视觉上可以区分的边界都被标记和着色。
🦆
在检查相邻网格块时,为什么遇到已访问的网格块就跳过不再检查?这是否会导致漏掉某些边界条件判断?
跳过已访问的网格块是为了避免重复处理和无限循环,这是BFS的常规操作。在本题解中,不会漏掉边界条件判断。因为一旦网格块被判断为边界并被着色,在整个BFS过程中,无论是从哪个方向访问,这个状态都不会改变。因此,即使跳过了已访问的网格块,判断边界的逻辑也已经在首次访问时完成了。
🦆
算法中对于边界的定义是否包括了所有可能的边界条件,例如在角落或者完全被同色网格包围但接触边缘的情况?
是的,算法的边界定义包括了所有可能的边界情况。物理边界包括网格的外围边缘,即最外层的行和列。此外,任何接触到不同颜色的网格块,即使是位于角落或内部但靠近物理边缘的网格块,都被视为边界。通过这种方式,算法确保所有视觉和逻辑上的边界都被考虑和处理。

相关问题

岛屿的周长

给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。

网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

 

示例 1:

输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
输出:16
解释:它的周长是上面图片中的 16 个黄色的边

示例 2:

输入:grid = [[1]]
输出:4

示例 3:

输入:grid = [[1,0]]
输出:4

 

提示:

  • row == grid.length
  • col == grid[i].length
  • 1 <= row, col <= 100
  • grid[i][j]01