zoukankan      html  css  js  c++  java
  • 529. Minesweeper扫雷游戏

    [抄题]:

    Let's play the minesweeper game (Wikipediaonline game)!

    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.

    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:

     

    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:

    Input: 
    
    [['E', 'E', 'E', 'E', 'E'],
     ['E', 'E', 'M', 'E', 'E'],
     ['E', 'E', 'E', 'E', 'E'],
     ['E', 'E', 'E', 'E', 'E']]
    
    Click : [3,0]
    
    Output: 
    
    [['B', '1', 'E', '1', 'B'],
     ['B', '1', 'M', '1', 'B'],
     ['B', '1', '1', '1', 'B'],
     ['B', 'B', 'B', 'B', 'B']]
    
    Explanation:
    

     [暴力解法]:

    时间分析:

    空间分析:

     [优化后]:

    时间分析:

    空间分析:

    [奇葩输出条件]:

    [奇葩corner case]:

    [思维问题]:

    没啥思路啊,不知道怎么统计雷的数量:单独新开一个函数,for i for j两层循环就行了。

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    [一句话思路]:

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    [一刷]:

    1. dsf开始的条件是一个符合条件的点,直接带入公式就行了,主函数里不再需要做for循环
    2. dfs变化的条件是board[i][j] == 'M'首次出现的条件,后续只需要count++就行了
    3. dfs退出的条件是x太大太小、y太大太小、矩阵中某点不符合规律
    4. dfs的signature是x和x的范围m,y和y的范围n,矩阵名字。

    [二刷]:

    1. board[i][j] != 'E'表示已经走过了,dfs不用再走

    [三刷]:

    [四刷]:

    [五刷]:

      [五分钟肉眼debug的结果]:

    [总结]:

    class Solution {
        int[][] dirs = {{0,1},{0,-1},{1,0},{1,1},{1,-1},{-1,0},{-1,1},{-1,-1}};
        
        public char[][] updateBoard(char[][] board, int[] click) {
            //initialization
            int m = board.length; int n = board[0].length;
            int x = click[0]; int y = click[1];
            
            //corner case
            if (board == null || click == null || m == 0 || n == 0 || click.length != 2) return result;
    
            
                    //if detected, turn to x
                    if (board[x][y] == 'M')
                        board[x][y] = 'X';
                    //if not, go dfs
                    else {
                    dfs(x, y, m, n, board, dirs);
                    }
           
            //return
            return board;
        } 
       
        public void dfs(int i, int j, int m, int n, char[][] board, int[][] dirs) {
            //exit
            if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'E') return ;
            
            //get the count, add num or go further dfs
            int count = adjMines(i, j, m, n, board);
            if (count > 0) {
                board[i][j] = (char)(count + '0');
                //change to char in 2 steps
            }else {
                board[i][j] = 'B';
                    for (int[] dir : dirs) {
                        dfs(i + dir[0], j + dir[1], m, n, board, dirs);
                    }
            }
        }
        
        public int adjMines(int x, int y, int m, int n, char[][] board) {
            //count = 0;
            int count = 0;
            //go in 4 dirs, add count if qualified
            for (int i = x - 1; i <= x + 1; i++) {
                for (int j = y - 1; j <= y + 1; j++) {
                    if (0 <= i && i < m && 0 <= j && j < n 
                        && board[i][j] == 'M')
                        count++;
                }
            }
            return count;
        }
    }
        
        
        
    View Code

    [复杂度]:Time complexity: O(mn) Space complexity: O(1)

    [算法思想:迭代/递归/分治/贪心]:

    [关键模板化代码]:

    [其他解法]:

    [Follow Up]:

    [LC给出的题目变变变]:

     [代码风格] :

     [是否头一次写此类driver funcion的代码] :

     [潜台词] :

  • 相关阅读:
    前置++和后置++的区别
    snmp数据包分析
    [codeforces538E]Demiurges Play Again
    [codeforces538D]Weird Chess
    [BZOJ3772]精神污染
    [BZOJ4026]dC Loves Number Theory
    [BZOJ1878][SDOI2009]HH的项链
    [BZOJ3658]Jabberwocky
    [BZOJ3932][CQOI2015]任务查询系统
    [BZOJ3551][ONTAK2010]Peaks加强版
  • 原文地址:https://www.cnblogs.com/immiao0319/p/9417750.html
Copyright © 2011-2022 走看看