uacs2024

导航

leetcode1034. 边界着色

1034. 边界着色

写出来的总是有莫名的溢出。

直接看题解

首先要找到包含 (row, col) 的同色连通集 S。
其次在S中找到S的边界,所谓S的边界呢,就是连同集中没有被***格包围的网格。
然后将这些边界的格子染成color。

从(row, col)出发,进行dfs,遍历所有相邻的点。用visited标记访问状态。
如果已经访问过直接返回。
如果颜色不同,直接返回。
如果颜色和起点相同,说明还处于连通集中;

那我们如何判断边界呢?
只需要数相邻的节点是不是4个节点都和自己颜色相同,只要有一个不同,我们就知道这个节点是在边界上的
当然我们需要标记出来,但如果直接修改则会影响其他节点dfs过程中对边界的判断;所以我们可以用一个「特殊色」,也就是网格中本来不存在的颜色去标记这种边界

其他dfs判断的时候只要把「起点颜色」和「特殊色」都当作「起点颜色」即可。

最后再把所有「特殊色」换成「目标色」即可。

class Solution {
public:
    vector<vector<int>> visited; // 记录单元格是否被访问过
    int dx[4] = {1, -1, 0, 0};  // 四个方向的x坐标变化:下、上、右、左
    int dy[4] = {0, 0, 1, -1};  // 四个方向的y坐标变化:下、上、右、左
    int m; // 网格的行数
    int n; // 网格的列数

    // 深度优先搜索函数
    // si, sj: 当前搜索的单元格坐标
    // target: 目标颜色值(需要标记边界的连通分量的颜色)
    void dfs(vector<vector<int>>& grid, int si, int sj, int target) {
        // 如果当前单元格已被访问过,直接返回
        if (visited[si][sj])  return;
        // 标记当前单元格为已访问
        visited[si][sj] = 1;
        // 如果当前单元格颜色不是目标颜色,返回
        if (grid[si][sj] != target) return;

        int cnt = 0; // 计数器,记录满足条件的相邻单元格数量
        // 检查四个方向
        for (int d = 0; d < 4; d++) {
            int i = si + dx[d]; // 计算相邻单元格的行坐标
            int j = sj + dy[d]; // 计算相邻单元格的列坐标
            // 检查相邻单元格是否在网格范围内
            if (i < m && i >= 0 && j < n && j >= 0) {
                // 如果相邻单元格是目标颜色或已被标记为边界(值为0)
                if (grid[i][j] == target || grid[i][j] == 0) {
                    cnt++; // 增加计数器
                    dfs(grid, i, j, target); // 递归搜索相邻单元格
                }
            }
        }
        // 如果四个相邻单元格不都满足条件,则当前单元格是边界
        if (cnt != 4) grid[si][sj] = 0; // 标记为边界(暂时用0表示)
    }

    // 主函数:给网格的连通分量边界着色// row, col: 起始单元格坐标
    // color: 要使用的颜色
    vector<vector<int>> colorBorder(vector<vector<int>>& grid, int row, int col, int color) {
        m = grid.size(); // 获取网格行数
        n = grid[0].size(); // 获取网格列数
        visited = vector<vector<int>>(m, vector<int>(n, 0)); // 初始化访问矩阵

        int target = grid[row][col]; // 获取目标颜色值

        // 从起始点开始DFS,标记所有边界单元格为0
        dfs(grid, row, col, target);
        
        // 遍历整个网格,将所有标记为0的单元格(边界)着色为目标颜色
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 0) grid[i][j] = color;
            }
        }

        return grid; // 返回处理后的网格
    }
};

 

posted on 2025-03-27 20:03  ᶜʸᵃⁿ  阅读(13)  评论(0)    收藏  举报