leetcode529. Minesweeper

題目要求

Let's play the minesweeper game (Wikipedia),online game)!java

You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine,'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine.git

Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules:ide

  1. If a mine ('M') is revealed, then the game is over - change it to 'X'.
  2. If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively.
  3. If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines.
  4. Return the board when no more squares will be revealed.

Example 1:this

Input:spa

[['E', 'E', 'E', 'E', 'E'],
 ['E', 'E', 'M', 'E', 'E'],
 ['E', 'E', 'E', 'E', 'E'],
 ['E', 'E', 'E', 'E', 'E']]

Click : [3,0]code

Output:blog

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'M', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

Explanation:
遞歸

Example 2:遊戲

Input:ip

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'M', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

Click : [1,2]

Output:

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'X', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

Explanation:

Note:

  1. The range of the input matrix's height and width is [1,50].
  2. The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square.
  3. The input board won't be a stage when game is over (some mines have been revealed).
  4. For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares.

玩過掃雷遊戲的同窗應該熟悉掃雷的規則,這題的目標在於模擬掃雷遊戲,它給了一塊已經完成一部分操做的掃雷面板,而且輸入了下一步點擊的位置。要求輸出執行此次點擊後面板的最新狀態。

其中M表示隱藏的雷,X表示被點開的雷。E表示未被點開的空格,B表示被點開的空格,數字1到8表示距離該格子一圈一共有幾個雷。

當玩家點擊了格子後,一共有三種狀況

  1. 點中了M,則將該格子更新爲X,遊戲結束
  2. 點中了B,且周圍有雷,則記錄該格子周圍一共幾個雷,並將數量標記到這個格子上
  3. 點中了B,且周圍無雷,則繼續向周圍一圈排雷。

思路和代碼

這是一道典型的經過廣搜或是深搜解決的題目。廣搜即以雷區爲中心,每次向外搜索一圈,深搜則是搜索到全是雷區爲止。廣搜代碼以下:

public char[][] updateBoard(char[][] board, int[] click) {  
    char clickValue = board[click[0]][click[1]];  
    if (clickValue == 'M') {  
        board[click[0]][click[1]] = 'X';  
    } else if (clickValue == 'E') {  
        //廣度優先遍歷  
  Queue<int[]> queue = new LinkedList<>();  
        queue.offer(click);  
        //8個方向  
  int[][] directions = new int[][]{  
            {0, 1},  
            {0, -1},  
            {-1, 0},  
            {1, 0},  
            {-1, -1},  
            {-1, 1},  
            {1, 1},  
            {1,-1}  
        };  
        while (!queue.isEmpty()) {  
            int[] tmpClick = queue.poll();  
            int countOfMine = 0;  
            List<int[]> emptyCells = new ArrayList<>();  
            for (int\[] direction : directions) {  
                int rowIndex = direction[0] + tmpClick[0];  
                int columnIndex = direction[1] + tmpClick[1];  
                if (rowIndex < 0 || rowIndex >= board.length || columnIndex < 0 || columnIndex >= board[0].length) {  
                    continue;  
                }  
                if (board[rowIndex][columnIndex] == 'M') {  
                    countOfMine++;  
                } else if (board[rowIndex][columnIndex] == 'E') {  
                   emptyCells.add(new int[]{rowIndex, columnIndex});  
                }  
            }  
            if (countOfMine == 0) {  
                board[tmpClick[0]][tmpClick[1]] = 'B';  
                //防止重複遍歷,先將其置爲B  
  for (int[] emptyCell : emptyCells) {  
                    board[emptyCell[0]][emptyCell[1]] = 'B';  
                }  
                queue.addAll(emptyCells);  
            } else {  
                board[tmpClick[0]][tmpClick[1]] = (char)('0' + countOfMine);  
            }  
        }  
    }  
    return board;  
}

深搜代碼以下:

public char[][] updateBoard2(char[][] board, int[] click) { 
    int m = board.length, n = board[0].length;  
    int row = click[0], col = click[1];  
  
    if (board[row][col] == 'M') { // Mine  
  board[row][col] = 'X';  
    }  
    else { // Empty  
 // Get number of mines first.  int count = 0;  
        for (int i = -1; i < 2; i++) {  
            for (int j = -1; j < 2; j++) {  
                if (i == 0 && j == 0) continue;  
                int r = row + i, c = col + j;  
                if (r < 0 || r >= m || c < 0 || c < 0 || c >= n) continue;  
                if (board[r][c] == 'M' || board[r][c] == 'X') count++;  
            }  
        }  
  
        if (count > 0) { // If it is not a 'B', stop further DFS.  
  board[row][col] = (char)(count + '0');  
        }  
        else { // Continue DFS to adjacent cells.  
 //遞歸的進行深度優先遍歷  board[row][col] = 'B';  
            for (int i = -1; i < 2; i++) {  
                for (int j = -1; j < 2; j++) {  
                    if (i == 0 && j == 0) continue;  
                    int r = row + i, c = col + j;  
                    if (r < 0 || r >= m || c < 0 || c < 0 || c >= n) continue;  
                    if (board[r][c] == 'E') updateBoard(board, new int[] {r, c});  
                }  
            }  
        }  
    }  
  
    return board;  
}
相關文章
相關標籤/搜索