leetcodeブラッシング日記 - 【130.囲み】

一緒に創造し、成長するために一緒に働きましょう!「ナゲッツデイリー新プラン・8月アップデートチャレンジ」参加32日目、イベント詳細はこちら

トピックの説明

いくつかの文字 'X' と 'O' で構成される mxn マトリックス ボードが与えられ、'X' で囲まれたすべての領域を見つけ、これらの領域のすべての 'O' を 'X' で埋めます。  

例 1:

画像.png

入力: 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」で埋められます。2 つの要素が水平または垂直に隣接している場合、これらの要素は「接続されている」と言われます。例 2:

入力: board = [["X"]] 出力: [["X"]]  

ヒント:

  • m == ボードの長さ
  • n == ボード[i].長さ
  • 1 <= m、n <= 200
  • board[i][j] は「X」または「O」

問題解決のアイデア

给定一个二维数组board,数组中元素只包含'O','X'。将二位数数组中所有不和边界'O'直接或间接关联的'O'元素替换成'X'。

根据题意,这道题的重点就是要找出所有与边界'0'直接或间接关联的点

比如点(1,0)为'0',则与它直接关联的点有(2,0),(1,1),(0,0)。即对原坐标进行四个方向的加减(1,0),(-1,0),(0,1),(0,-1);

即上下左右四个方向,然后这几个点又有直接关联的上下左右四个点,依次类推,直到这些关联的点元素不是'O';

所以解这道题有深度优先和广度优先两种选择;

深度优先

遍历上、下、左、右边界的元素,每一次找一个方向上所有的直接或间接与'O'关联的元素,将它们替换成其它元素,比如'B';

遍历完成之后将原数组进行遍历,找到不是'B'且是'O'的元素,将它们设置成'X',然后再将元素值为'B'的替换成'O';

广度优先

第一层遍历获取上、下、左、右边界上所有的'O'元素,将它们设置成其它的元素,比如'B',将它放入队列queue中;

遍历queue,截止条件为queue为空,每一次循环从queue中弹出栈顶元素,然后对原坐标进行四个方向的加减(1,0),(-1,0),(0,1),(0,-1);

获取与当前元素直接关联的节点,判断如果计算出来的位置的元素为'O',则将这个节点的位置放入queue中,并且将该元素修改为'B';

キューの内容が空の場合、つまり、境界 'O' に直接的または間接的に関連する 2 次元配列内のすべての要素が見つかったとき、2 次元配列がトラバースされ、要素value is not 'B' and the element value is 'O'. 要素を 'X' に置き換えてから、要素値 'B' を 'O' に置き換えます。

コード

public void solve(char[][] board) {
    n = board.length;
    m = board[0].length;
    // 深度优先
    // 第一层左右边界
    for (int i=0; i < n;i ++) {
        // 第一列
        dfs(board,i,0);
        // 末尾列
        dfs(board,i,m-1);
    }

    // 上下边界
    for (int i=0; i < m;i ++) {
        // 第一列
        dfs(board,0,i);
        // 末尾列
        dfs(board,n-1,i);
    }
    // System.out.print("[");
    for (int i=0;i<n;i++) {
        for (int j=0;j<m;j++) {
            if (board[i][j] != 'B') {
                board[i][j] = 'X';
            } else {
                board[i][j] = 'O';
            }
        }
        // System.out.print(Arrays.toString(board[i]));
    }
    // System.out.print("]");
}

private void dfs(char[][] board, int x, int y) {
    if (x < 0 || x >= n || y < 0 || y >= m || board[x][y] != 'O') {
        // 截止条件,四个方向的值超出矩阵范围或者当前查找元素不是目标替换元素 则直接返回
        return;
    }
    // 修改当前查找元素为'B'
    board[x][y] = 'B';
    // 递归查找四个方向的元素
    for (int[] ints : direction) {
        dfs(board,x+ints[0],y+ints[1]);
    }
}
复制代码

おすすめ

転載: juejin.im/post/7136827321159254029