来一种刻在骨子里的模板题

100 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述:

130. 被围绕的区域

给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。  

示例 1:

输入: board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]
输出: [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]
解释: 被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂直方向相邻,则称它们是“相连”的。

二、思路分析:

一看到这样的矩阵一下就想到了深度搜索和广度搜索,两者是差不多的,那我们就用深搜索试一下这题,首先题目说了要包围着的“O”才不保留,也就是说只有矩阵周围的“O”和与之连接在一起的“O”会被保留起来,那么我们只需要对矩阵的四个边界进行遍历,然后对值是“O”的进行深搜,把遍历到的所有“O”,都保留起来就可以了,那么我们怎么保留呢?这里就要用一点点及技巧了,一开始我是想着用一个拷贝数组来保留这个数组,然后原数组,然后再对拷贝数组进行刚才深搜的操作,看似没有什么问题,但是一跑就栈溢出了,仔细一想原来是如果全地图都是“O”的话,那么从A搜到B再从B搜到A就会陷入死递归,那么只能换个办法了。后来发现是自己想复杂了,其实我们只要在边界深搜的时候,把遍历到的“O”,变成其他的任意字符(除了O和X)就可以了,这里我用了"-",然后边界搜索完成后,我们只要把整个矩阵进行一次遍历,把值为“-”的变成“O”,其他的全部变成“X”,那么这道题目就解决了。

  • 定义一个方向数组,为了美观,当然也可以没有。
  • 对矩阵边界进行深搜,注意这里的边界的四个角落不要重复了!!!
  • 深搜函数的书写,如果新的下标没有超过边界且为“O”,那么久继续递归下去。
  • 遍历整个矩阵,查看是“-”的地方置为“O”,其他的置之为“X”。
  • 完美。

三、AC 代码:

代码一:

/**
 * @param {character[][]} board
 * @return {void} Do not return anything, modify board in-place instead.
 */
var solve = function(board) {
    let m=board.length,n=board[0].length;
    let direction=[[0,1],[0,-1],[1,0],[-1,0]];
    for(let i=0;i<m;i++){
        if(board[i][0]==='O'){
            dfs(i,0);
        }
        if(board[i][n-1]==='O'){
            dfs(i,n-1);
        }
    }
    for(let j=1;j<n-1;j++){
        if(board[0][j]==='O'){
            dfs(0,j);
        }
        if(board[m-1][j]==='O'){
            dfs(m-1,j);
        }
    }
    for(let i=0;i<m;i++){
        for(let j=0;j<n;j++){
            if(board[i][j]==='-'){
                board[i][j]='O';
            }else{
                board[i][j]='X';
            }
        }
    }
    function dfs(x,y){
        board[x][y]='-';
        for(let i=0;i<4;i++){
            let curX=x+direction[i][0],curY=y+direction[i][1];
            if(curX<m&&curX>=0&&curY>=0&&curY<n&&board[curX][curY]==='O'){
                dfs(curX,curY);
            }
        }
    }
};

四、总结:

对于这种矩阵的覆盖问题很适合深搜和广搜,多注意边界细节!