1. 程式人生 > 實用技巧 >130.被圍繞的區域

130.被圍繞的區域

給定一個二維的矩陣,包含'X'和'O'(字母 O)。

找到所有被 'X' 圍繞的區域,並將這些區域裡所有的'O' 用 'X' 填充。

示例:

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,表示:與邊界相鄰,未被包圍,且已經遍歷過了
  •所有邊界都遍歷完後,對矩陣進行 替換、還原的操作。

class Solution {
    public void solve(char[][] board) {
        if(board.length == 0 || board[0].length == 0) return;
        int m = board.length, n = board[0].length;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                
boolean isEdge = (i == 0 || i == m-1 || j == 0 || j == n-1);//是否為邊界 if(isEdge && board[i][j] == 'O') DFS(board, i, j); //邊界,且當前字母為 'O',開始深搜 } } for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(board[i][j] == 'X') continue
; else if(board[i][j] == 'O') board[i][j] = 'X'; //未被標記過的 O,表示被包圍了,替換為 X else if(board[i][j] == 'A') board[i][j] = 'O'; //標記過的O,與邊界相鄰,未包圍,還原為 O } } } private void DFS(char[][] board, int x, int y){ if(x < 0 || x >= board.length || y < 0 || y >= board[0].length || board[x][y] == 'X' || board[x][y] == 'A') return; board[x][y] = 'A'; //深搜時,與邊界上的 O 相鄰,標記為走過 DFS(board,x-1, y);// DFS(board,x+1, y);// DFS(board,x, y-1);// DFS(board,x, y+1);// } }