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:

Example 2:

Input: 

[['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.
分析

类似扫雷游戏,初始点击位置一定是有效的,遵循四条规则进行点击:

1.翻开为M,改为X,游戏结束。

2.翻开为E,如果所有邻居中没有找到M,将E改为B,并把相邻未翻开的位置记录下来,下次进行点击。

3.翻开E,如果周围至少有一个M,将E改为周围存在的雷数。

4.当没有要点击的位置之后返回白板。

比较慢的一个版本代码是分别写函数寻找上方,下方,左侧,右侧的位置,并且也是邻居为E时保存位置,不过因为直接保存到了click中,因此总会有erase操作,时间会很慢,另外一个版本是宽度优先遍历,用两个for循环代表坐标从-1,+0,+1变化,并且用临时变量保存邻居信息,只有需要保存的时候才会压入,减少了很多erase操作。

class Solution {
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
    deque<pair<int, int>> q({ { click[0], click[1] } });//用队列保存点击位置
    while (!q.empty()) {
        auto c = q.front().first, r = q.front().second, mines = 0;
        vector<pair<int, int>> neighbours;//用向量保存邻居位置
        if (board[c][r] == 'M') board[c][r] = 'X';
        else for (auto i = -1; i <= 1; ++i) {//横纵坐标从当前位置分别-1,+0,+1覆盖八个方向
            for (auto j = -1; j <= 1; ++j) {
                if (c + i >= 0 && r + j >= 0 && c + i < board.size() && r + j < board[0].size()) {//判断是否越界
                    if (board[c + i][r + j] == 'M') ++mines;
                    else if (mines == 0 && board[c + i][r + j] == 'E') neighbours.push_back({ c + i, r + j});//如果没找到雷并且邻居是空,则保存邻居位置
                }
            }
        }
        if (mines > 0) board[c][r] = '0' + mines;//根据雷的数量决定点击位置的信息
        else for (auto n : neighbours) {
            board[n.first][n.second] = 'B';
            q.push_back(n);
        }
        q.pop_front();
    }
    return board;
}
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值