题目链接:https://leetcode-cn.com/problems/coloring-a-border/
    题目详情:
    image.png

    解题要点:

    • 从一个点遍历整个连通量
    • 将连通量的边界设置为其他颜色

    dfs解法:从给定点开始遍历,借助标记数组 visited 来实现连通量的遍历。然后对连通量中的每一个点,加个判断(判断是否为边界)就完成任务了

    1. class Solution {
    2. List<int []> list;
    3. boolean[][] visited;
    4. int n, m;
    5. int originColor;
    6. //判断当前连通量的点是否为边界点
    7. boolean judge(int[][] grid, int row, int col){
    8. if(row == 0 || row == n-1){
    9. return true;
    10. }
    11. if(col == 0 || col == m-1){
    12. return true;
    13. }
    14. if(row -1 >= 0){
    15. if(grid[row][col] != grid[row-1][col]){
    16. return true;
    17. }
    18. }
    19. if(col + 1 < m) {
    20. if (grid[row][col] != grid[row][col + 1]) {
    21. return true;
    22. }
    23. }
    24. if(row + 1 < n){
    25. if(grid[row][col] != grid[row+1][col]){
    26. return true;
    27. }
    28. }
    29. if(col - 1 >= 0){
    30. if(grid[row][col] != grid[row][col-1]){
    31. return true;
    32. }
    33. }
    34. return false;
    35. }
    36. void helper(int[][] grid, int row, int col, int color){
    37. //防止下标越界
    38. if(row < 0 || row >= n || col < 0 || col >=m){
    39. return;
    40. }
    41. //判断当前遍历到的点是否属于同一个连通量(题目给定点的连通量)
    42. if(grid[row][col] != originColor){
    43. return;
    44. }
    45. //防止在遍历连通量时产生死循环
    46. if(visited[row][col]){
    47. return;
    48. }
    49. //标记当前点已经访问
    50. visited[row][col] = true;
    51. //加个判断,如果是边界点,记录该点的坐标
    52. //如果把这个判断取出,其实就是dfs遍历连通量的模板
    53. if(judge(grid, row, col))
    54. list.add(new int[]{row, col});
    55. //对 上、右、下、左 四个方向进行搜索
    56. helper(grid, row-1, col, color);
    57. helper(grid, row, col+1, color);
    58. helper(grid, row+1, col, color);
    59. helper(grid, row, col-1, color);
    60. }
    61. public int[][] colorBorder(int[][] grid, int row, int col, int color) {
    62. n = grid.length;
    63. m = grid[0].length;
    64. visited = new boolean[n][m];
    65. list = new ArrayList<>();
    66. originColor = grid[row][col];
    67. helper(grid, row, col, color);
    68. //那些为边界点的坐标,在grid中赋值,完成题目要求
    69. for(int[] dir : list){
    70. int x = dir[0];
    71. int y = dir[1];
    72. grid[x][y] = color;
    73. }
    74. return grid;
    75. }
    76. }

    时间复杂度:O(m n)。
    空间复杂度:O(m
    n)。

    bfs解法:从给定点逐层往外扩散,还是搜索四个方向,注意:bfs同样需要标记数组来防止元素多次访问

    class Solution {
        int n, m;
        boolean judge(int[][] grid, int row, int col){
            if(row < 0 || row >= n || col < 0 || col >= m){
                return false;
            }
            if(row == 0 || row == n-1){
                return true;
            }
            if(col == 0 || col == m-1){
                return true;
            }
            if(row -1 >= 0){
                if(grid[row][col] != grid[row-1][col]){
                    return true;
                }
            }
            if(col + 1 < m) {
                if (grid[row][col] != grid[row][col + 1]) {
                    return true;
                }
            }
            if(row + 1 < n){
                if(grid[row][col] != grid[row+1][col]){
                    return true;
                }
            }
            if(col - 1 >= 0){
                if(grid[row][col] != grid[row][col-1]){
                    return true;
                }
            }
            return false;
        }
    
        public int[][] colorBorder(int[][] grid, int row, int col, int color) {
            n = grid.length;
            m = grid[0].length;
    
            boolean[][] visited = new boolean[n][m];
            List<int[]> list = new ArrayList<>();
            int originColor = grid[row][col];
            Queue<int[]> q = new LinkedList<>();
            q.add(new int[]{row, col});
    
            int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
            while(!q.isEmpty()){
                int size = q.size();
                for(int k = 0; k < size; k++){
                    int[] point = q.poll();
                    if(judge(grid, point[0], point[1])){
                        list.add(new int[]{point[0], point[1]});
                    }
                    visited[point[0]][point[1]] = true;
                    for(int i = 0; i < 4; i++){
                        int x = point[0] + dirs[i][0];
                        int y = point[1] + dirs[i][1];
                        if(((x >= 0 && x < n) && (y >= 0 && y < m)) && !visited[x][y] && grid[x][y] == originColor){
                            q.add(new int[]{x, y});
                        }
                    }
                }
            }
            for(int[] dir : list){
                int x = dir[0];
                int y = dir[1];
                grid[x][y] = color;
            }
            return grid;
    
        }
    }
    

    时间和空间复杂度与dfs相同