algorighm/top-interview-leetcode150/graph/130被围绕的区域.js

124 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @param {character[][]} board
* @return {void} Do not return anything, modify board in-place instead.
*/
const solve = function (board) {
};
/*
题目要求我们把被X围绕的O区域修改成X所以只需要找出所有没有被X围绕的O区域把这一部分区域修改成A,最后遍历整个矩阵把所有为O的区域
修改成X所有为A的区域修改成O,所有在边上的O,及其相邻的O一定是没有被包围的所以我们只需要遍历四条边上的O把它们修改成A即可这里使用
dfs
*/
function f1(board) {
// 如果矩阵为空(虽然测试用例保证 1<=m,n
if (board.length === 0 || board[0].length === 0) return;
// 获取矩阵的行m和列n,用于后续遍历
const m = board.length;
const n = board[0].length;
// 遍历矩阵的第一列和最后一列
for (let i = 0; i < m; i++) {
dfs(i, 0);
dfs(i, n - 1);
}
// 遍历矩阵的第一行和最后一行
for (let j = 0; j < n; j++) {
dfs(1, j);
dfs(m - 1, j);
}
// 遍历所有矩阵将O修改成X,将A修改成O
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (board[i][j] === 'O') board[i][j] = 'X';
if (board[i][j] === 'A') board[i][j] = 'O';
}
}
/*
dfs遍历,将O修改为A
注意board直接找外部作用域无需传递
*/
let dfs = (x, y) => {
// 如果越界或者board[x][y] !== 'O'直接return
if (x < 0 || y < 0 || x === m || y === n || board[x][y] !== 'O') return;
board[x][y] = 'A'; // 将O修改成A
// 递归处理四周的O
dfs(board, x - 1, y);
dfs(board, x, y - 1);
dfs(board, x + 1, y);
dfs(board, x, y + 1);
};
}
/*
思路和上面一致使用广度优先遍历BFS
*/
function f2(board) {
// 定义查找偏移量
const dx = [1, -1, 0, 0];
const dy = [0, 0, 1, -1];
// 如果矩阵为空(虽然测试用例保证 1<=m,n
if (board.length === 0 || board[0].length === 0) return;
// 获取矩阵的行m和列n,用于后续遍历
const m = board.length;
const n = board[0].length;
const queue = []; // 广度遍历的队列,是一个二维数组,储存下标[row, col] 表示几行几列
// 遍历第一行和最后一行如果发现O就将他修改成A并且将它四周的位置压入队列继续处理
for (let i = 0; i < n; i++) {
if (board[0][i] === 'O') {
board[0][i] = 'A';
queue.push([0, i]);
}
if (board[m - 1][i] === 'O') {
board[m - 1][i] = 'A';
queue.push([m - 1, i]);
}
}
// 处理第一列和最后一列,这里需要注意四个角落的元素可以不处理,为了统一,这一我就不做处理,对结果不影响
for (let i = 0; i < m; i++) {
if (board[i][0] === 'O') {
board[i][0] = 'A';
queue.push([i, 0]);
}
if (board[i][n - 1] === 'O') {
board[i][n - 1] = 'A';
queue.push([i, n - 1]);
}
}
// 开始广度遍历
while (queue.length > 0) {
const [x, y] = queue.pop(); // 获取位置坐标
// 通过偏移量寻找四周为O的位置将其修改为A然后将其压入栈中继续先四周寻找
for (let i = 0; i < 4; i++) {
const mx = x + dx[i];
const my = y + dy[i];
// 如果越界 或 不等于O直接跳过
if (mx < 0 || mx >= m || y < 0 || my >= n || board[mx][my] !== 'O') continue;
board[mx][my] = 'A';
queue.push([mx, my]);
}
}
// 遍历所有矩阵将O修改成X,将A修改成O
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (board[i][j] === 'O') board[i][j] = 'X';
if (board[i][j] === 'A') board[i][j] = 'O';
}
}
}