529. Minesweeper\74. Search a 2D Matrix

本文介绍了解决扫雷游戏问题的递归算法及二维矩阵中搜索特定值的高效算法。通过具体示例展示了如何在给定点击位置后更新游戏面板的状态,以及如何在一个按行递增排序的矩阵中查找目标值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

529. Minesweeper

题目描述

Let’s play the minesweeper game (Wikipedia, online 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']]

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']]

这道题目的关键在于知道题目的意思,也就是扫雷的规则。

其实英文描述已经把题目意思讲得很清楚了,那就是:

  • 点到M的话,那就是把M变成X并返回。
  • 如果点到E的话,那么就把E变成周围雷的数量(大于0的时候)或者是变成‘B’。如果周围雷的数量为0的时候,把周围(8个邻居)为E的节点push到队列里。

代码实现

class Solution {
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
        int row = click[0], col = click[1], m = board.size(), n = m?board[0].size():0;
        if(!m)  return board;

        // 从【0,0】开始顺时针
        int loc[] = {-1, -1, -1, 0, 1, 1, 1, 0, -1, 0, 1, 1, 1, 0, -1, -1};
        int retri[] = {-1, 0, 1, 0, 0, 1, 0, -1};
        if(board[row][col] == 'M')  board[row][col] = 'X';
        else {
            queue<pair<pair<int, int>, int>> mque;
            queue<pair<int, int>> que;
            board[row][col] = 'B';
            que.push(make_pair(row, col));

            while(!que.empty()) {
                int num_mine = 0;
                int i = que.front().first, j = que.front().second;
                que.pop();

                for(int k = 0; k < 8; k++)  
                    if(i + loc[k] >= 0 && i + loc[k] < m && j + loc[k+8] >= 0 && j + loc[k+8] < n) 
                        if(board[i + loc[k]][j + loc[k+8]] == 'M') num_mine++;

                if(num_mine) board[i][j] = char('0'+num_mine);   

                for(int k = 0; k < 8; k++) {
                    if(!num_mine && i + loc[k] >= 0 && i + loc[k] < m && j + loc[k+8] >= 0 && j + loc[k+8] < n) 
                        if(board[i + loc[k]][j + loc[k+8]] == 'E') {
                            board[i + loc[k]][j + loc[k+8]] = 'B'; que.push(make_pair(i + loc[k], j + loc[k+8]));
                        }
                }
            }
        }

        return board;
    }
};

74. Search a 2D Matrix

题目描述

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

Given target = 3, return true.

首先使用二分法来计算属于哪一行,然后使用二分法来计算属于哪一个。

代码实现

需要注意判断vector为空的情况。

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& mat, int tar) {
        int m = mat.size(), n = m?mat[0].size():0;
        if(!m || !n) return false;
        int mid = m >> 1, fst = 0, lst = m - 1;
        if(mat[0][0] > tar || mat[m-1][n-1] < tar) return false;
        while(fst <= lst) {
            mid = (fst + lst + 1) >> 1;
            if(mat[mid][0] <= tar && mat[mid][n - 1] >= tar)  break;
            else if(mat[mid][0] > tar)  lst = mid - 1;
            else if(mat[mid][n - 1] < tar)  fst = mid + 1;
        }
        fst = 0, lst = n - 1;
        int mmid = 0;
        while(fst <= lst) {
            mmid = (fst + lst + 1) >> 1;
            if(mat[mid][mmid] == tar) return true;
            else if(mat[mid][mmid] > tar) lst = mmid - 1;
            else fst = mmid + 1;
        }
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值