题目

给定一个二维的矩阵,包含 ‘X’ 和 ‘O’(字母 O)。找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。

示例:

let board = [
    ["X", "X", "X", "X"],
    ["X", "O", "O", "X"],
    ["X", "X", "O", "X"],
    ["X", "O", "X", "X"]
]

运行你的函数后,矩阵变为:

board = [
    ["X", "X", "X", "X"],
    ["X", "X", "X", "X"],
    ["X", "X", "X", "X"],
    ["X", "O", "X", "X"]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/surrounded-regions

思路

找出所有边界上的’O’,并从边界上的’O’开始寻找相邻的’O’

  • 对于每一个边界上的 O,以它为起点,标记所有与它直接或间接相连的字母 O;
  • 最后遍历这个矩阵,对于每一个字母:
    • 如果该字母被标记过,则该字母为没有被字母 X 包围的字母 O,我们将其还原为字母 O;
    • 如果该字母没有被标记过,则该字母为被字母 X 包围的字母 O,我们将其修改为字母 X。

深度优先搜索

let row, col = 0;
function solve(board) {
    if (board == null || board.length == 0) {
        return;
    }
    row = board.length;
    col = board[0].length;
    for (let c = 0; c < col; c++) {	// 对矩阵的第一行与最后一行进行遍历
        dfs(board, 0, c);
        dfs(board, row - 1, c);
    }
    for (let r = 1; r < row - 1; r++) {	// 对矩阵的第一列与最后一列进行遍历(排除前一个for循环中包含的端点)
        dfs(board, r, 0);
        dfs(board, r, col - 1);
    }
    for (let i = 0; i < row; i++) {	// 深度优先搜索结束后,遍历矩阵,将为'O'的置为'X',将标记过的值还原为'O'
        for (let j = 0; j < col; j++) {
            board[i][j] === "O" && (board[i][j] = "X");
            board[i][j] === "Y" && (board[i][j] = "O");
        }
    }
};

// 深度优先搜索
function dfs(board, x, y) {
	// 判断是否越界,矩阵值是否为'O'
    if (x < 0 || y < 0 || x >= row || y >= col || board[x][y] != "O") {
        return;
    }
    // 满足条件,进行标记
    board[x][y] = "Y";
    // 对其四周的值进行深度优先搜索
    dfs(board, x + 1, y);
    dfs(board, x, y + 1);
    dfs(board, x, y - 1);
    dfs(board, x - 1, y);
}

广度优先搜索

let row, col = 0;
function solve(board) {
    const dx = [1, -1, 0, 0];
    const dy = [0, 0, 1, -1];
    if (board == null || board.length == 0) {
        return;
    }
    row = board.length;
    col = board[0].length;
    let quene = [];	// 初始化队列
    for (let c = 0; c < col; c++) {		// 首行与末行
        if (board[0][c] === "O") {
            quene.push([0, c])	// 放入队列
        }
        if (board[row - 1][c] === "O") {
            quene.push([row - 1, c])
        }
    }
    for (let r = 1; r < row - 1; r++) {	// 首列与末列
        if (board[r][0] === "O") {
            quene.push([r, 0])
        }
        if (board[r][col - 1] === "O") {
            quene.push([r, col - 1])
        }
    }
    while (quene.length > 0) {	// 循环直至队列为空
        let x = quene[0][0];
        let y = quene[0][1];
        quene.shift();	// 移出队列
        board[x][y] = "Y";	
        for (let i = 0; i < 4; i++) {	// 将当前位置四周为'O'的坐标放入队列中
            let mx = x + dx[i];
            let my = y + dy[i];
            if (mx < 0 || my < 0 || mx >= row || my >= col || board[mx][my] != "O") {
                continue;
            }
            quene.push([mx, my])
        }
    }
	// 广度优先搜索结束后,遍历矩阵,将为'O'的置为'X',将标记过的值还原为'O'
    for (let i = 0; i < row; i++) {
        for (let j = 0; j < col; j++) {
            board[i][j] === "O" && (board[i][j] = "X");
            board[i][j] === "Y" && (board[i][j] = "O");
        }
    }
};

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

ES6中Set的使用 上一篇
ES6中Map的使用 下一篇