leetcode刷题第十一天--边界着色(DFS算法)

题目描述

给你一个大小为 m x n 的整数矩阵 grid ,表示一个网格。另给你三个整数 row、col 和 color 。网格中的每个值表示该位置处的网格块的颜色。

两个网格块属于同一 连通分量 需满足下述全部条件:

两个网格块颜色相同
在上、下、左、右任意一个方向上相邻
连通分量的边界 是指连通分量中满足下述条件之一的所有网格块:

在上、下、左、右任意一个方向上与不属于同一连通分量的网格块相邻
在网格的边界上(第一行/列或最后一行/列)
请你使用指定颜色 color 为所有包含网格块 grid[row][col] 的 连通分量的边界 进行着色,并返回最终的网格 grid 。

示例一:

输入:grid = [[1,1],[1,2]], row = 0, col = 0, color = 3
输出:[[3,3],[3,2]]

示例二:

输入:grid = [[1,2,2],[2,3,2]], row = 0, col = 1, color = 3
输出:[[1,3,3],[2,3,3]]

示例三:

输入:grid = [[1,1,1],[1,1,1],[1,1,1]], row = 1, col = 1, color = 2
输出:[[2,2,2],[2,1,2],[2,2,2]]

用通俗易懂的语言重新描述题目。。。

这道题真的光题目我就看了半小时。。。我一度怀疑这是语文题

1.连通区域:类似昨天的岛屿问题中的岛屿,有兴趣的小伙伴可以翻阅上一篇
岛屿问题题解

2.连通区域的边界:点本身就在数组的边缘,或者其上下左右四个点有一个不属于连通区域,我们要染色的目标就是这些边界点。

解题思路

这道题与岛屿问题十分类似,核心思想都是一样的,只不过我们找到连通区域的点后加一步判断其是不是连通区域的边界就可以了。

举个栗子

输入:

[1,2,1,2,1,2]
[2,2,2,2,1,2]
[1,2,2,2,1,2]
1
3
1

连通区域:
在这里插入图片描述
连通区域的边界:
在这里插入图片描述

代码实现(java)

class Solution {
    //标记原始的颜色
    int precolor;
    //标记是否被访问过
    boolean[][] flag ;
    public int[][] colorBorder(int[][] grid, int row, int col, int color) {
        precolor = grid[row][col];
        flag = new boolean[grid.length][grid[0].length];
        dfs(grid,row,col,color,precolor,flag);
        return grid;
    }

    public void dfs(int[][] grid, int row, int col, int color,int precolor,boolean[][] flag){
        //退出条件
        if(row<0||col<0||row>=grid.length||col>=grid[0].length||grid[row][col]!=precolor||flag[row][col])
        return;

        //程序能执行到这里说明找到的点和目标点属于同一个连通分量,且没有越界
        //判断是否是位于数组边界的点,是的话就进行染色
        if(flag[row][col]==false&&(row==0||row==grid.length-1||col==0||col==grid[0].length-1))
        grid[row][col] = color;

        //若这个点上下左右有一个点不属于该连通区域,该点就是连通区域的边界点
        if(isTrue(grid,row,col+1)||isTrue(grid,row,col-1)||isTrue(grid,row-1,col)||isTrue(grid,row+1,col))
        grid[row][col] = color;

        //该点标记为已访问过
        flag[row][col]=true;

        //继续进行深搜
        dfs(grid,row-1,col,color,precolor,flag);
        dfs(grid,row+1,col,color,precolor,flag);
        dfs(grid,row,col-1,color,precolor,flag);
        dfs(grid,row,col+1,color,precolor,flag);
        
    }

    public boolean isTrue (int[][] grid,int i,int j){
        //第一种情况,越界,这一步的目的是防止报错。
        if(i<0||i>=grid.length||j<0||j>=grid[0].length)
        return false;
        //未被访问过且,颜色与初始点的颜色不一样
        if(grid[i][j]!=precolor&&!flag[i][j])
        return true;
        //被访问过或者颜色与初始点一样
        return false;
    }
}

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值