Java naive solution with explanation


  • 2

    Make sure you know the rule of updating the board.

    1. When clicking on the unrevealed mine, just update the current cell to 'X'.
    2. When clicking on the cell with mines nearby (8 neighbors including diagonals), just update the count of mines in the neighborhood.
    3. When clicking on the cell with 0 mine nearby, all the 8 neighbors also need to be checked and updated. And since once a cell is visited, its character will be changed for sure, the board will record the visited cells itself so no worry about revisiting.

    ps: I know the format is somewhat stupid lol.

    public char[][] updateBoard(char[][] board, int[] click) {
        int x = click[0];
        int y = click[1];
        if(board[x][y] == 'M') board[x][y] = 'X';
        else if(countmines(board,x,y)>0) board[x][y] = (char)(countmines(board,x,y) + '0');
        else update(board,x,y);
        return board;
    }
    private void update(char[][] board, int i, int j){
        if(i<0||i>=board.length||j<0||j>=board[0].length) return;
        if(board[i][j]=='E'){
            if(countmines(board,i,j)==0) {
                board[i][j] = 'B';
                update(board,i,j-1);
                update(board,i-1,j);
                update(board,i,j+1);
                update(board,i+1,j);
                update(board,i-1,j-1);
                update(board,i+1,j+1);
                update(board,i+1,j-1);
                update(board,i-1,j+1);
            }
            else{
                board[i][j] = (char)(countmines(board,i,j) + '0');
            }
        }
    }
    
    private int countmines(char[][] board,int i, int j){ // just count mines in the neighborhood.
        int count = 0;
        if(i-1>=0&&board[i-1][j]=='M')count++;
        if(i+1<board.length&&board[i+1][j]=='M')count++;
        if(j-1>=0&&board[i][j-1]=='M')count++;
        if(j+1<board[0].length&&board[i][j+1]=='M')count++;
        if(i-1>=0&&j-1>=0&&board[i-1][j-1]=='M')count++;
        if(i+1<board.length&&j+1<board[0].length&&board[i+1][j+1]=='M') count++;
        if(i-1>=0&&j+1<board[0].length&&board[i-1][j+1]=='M') count++;
        if(i+1<board.length&&j-1>=0&&board[i+1][j-1]=='M') count++;
        return count;
    }

  • 0

    Similar approach, but with precalculated mines (could be useful in case of multiple clicks, as in a real game) and the neighbors are generated via 2 loops:

    public class Solution {
      public char[][] updateBoard(char[][] board, int[] click) {
        int y = click[0], x = click[1];
        if (isMine(board, y, x)) board[y][x] = 'X';
        else reveal(board, getInfo(board), y, x);
        return board;
      } 
      private int[][] getInfo(char[][] board) {
        int[][] info = new int[board.length][board[0].length];
        for (int y = 0; y < info.length; y++)
          for (int x = 0; x < info[y].length; x++)
            if (isMine(board, y, x))
              mark(info, board, y, x);
        return info;
      } 
      private void reveal(char[][] board, int[][] info, int y, int x) {
        if (isEmpty(board, y, x)) {
          if (info[y][x] == 0) {
            board[y][x] = 'B';
            for (int dy : new int[]{-1, 0, 1})
              for (int dx : new int[]{-1, 0, 1})
                reveal(board, info, y + dy, x + dx);
          } else board[y][x] = (char) ('0' + info[y][x]);
        }
      } 
      private boolean isMine(char[][] board, int y, int x)  { return isValid(board, y, x) && board[y][x] == 'M'; } 
      private boolean isEmpty(char[][] board, int y, int x) { return isValid(board, y, x) && board[y][x] == 'E'; } 
      private void mark(int[][] info, char[][] board, int y, int x) {
        for (int dy : new int[]{-1, 0, 1})
          for (int dx : new int[]{-1, 0, 1}) {
            int newY = y + dy, newX = x + dx;
            if (isValid(board, newY, newX))
              info[newY][newX]++;
          }
      } 
      private boolean isValid(char[][] board, int y, int x) { return y >= 0 && y < board.length && x >= 0 && x < board[y].length; }
    }
    

  • 1

    @Nakanu, you inverted x and y in the clicks, it's actually rather:

     int y = click[0], x = click[1];
    

  • 0
    J

    @paplorinc It doesn't matter at all whether you call in 'x' or 'y'. As long as it's consistent throughout the code.


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.