Leetcode 529. 扫雷游戏

1.题目基本信息##

1.1.题目描述

给你一个大小为 m x n 二维字符矩阵 board ,表示扫雷游戏的盘面,其中:

'M' 代表一个 未挖出的 地雷,
'E' 代表一个 未挖出的 空方块,
'B' 代表没有相邻(上,下,左,右,和所有4个对角线)地雷的 已挖出的 空白方块,
数字('1' 到 '8')表示有多少地雷与这块 已挖出的 方块相邻,
'X' 则表示一个 已挖出的 地雷。
给你一个整数数组 click ,其中 click = [clickr, clickc] 表示在所有 未挖出的 方块('M' 或者 'E')中的下一个点击位置(clickr 是行下标,clickc 是列下标)。

根据以下规则,返回相应位置被点击后对应的盘面:

如果一个地雷('M')被挖出,游戏就结束了- 把它改为 'X' 。
如果一个 没有相邻地雷 的空方块('E')被挖出,修改它为('B'),并且所有和其相邻的 未挖出 方块都应该被递归地揭露。
如果一个 至少与一个地雷相邻 的空方块('E')被挖出,修改它为数字('1' 到 '8' ),表示相邻地雷的数量。
如果在此次点击中,若无更多方块可被揭露,则返回盘面。

1.2.题目地址

https://leetcode.cn/problems/minesweeper/description

2.解题方法

2.1.解题思路

关键理解提议,然后使用广度优先搜索。

2.2.解题步骤

第一步,创建队列queue,和记忆化的集合visited

第二步,while循环从queue中弹出位置元素,直到queue为空

第三步,while中的循环规则,如果弹出的item已经遍历过了,则跳过。否则,获取相邻的点中雷的个数。如果相邻的雷数为0,则面板中标记当前的点为"B",并将相邻的点全部加到队列queue中。如果雷数不为0,则将当前的节点标记为相邻的雷数的字符串。

第四步,退出循环后返回board面板

3.解题代码

C++代码

class Solution {
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
        int rows=board.size(),cols=board[0].size();
        int arrx[8]={-1,-1,1,1,1,-1,0,0};
        int arry[8]={-1,1,-1,1,0,0,-1,1};
        set<pair<int,int>> visited;
        queue<pair<int,int>> que;
        que.emplace(click[0],click[1]);
        while(!que.empty()){
            auto item=que.front();
            que.pop();
            
            int x=item.first,y=item.second;
            if(visited.find(item)!=visited.end()){
                continue;
            }
            visited.emplace(x,y);
            

            if(board[x][y]=='M'){
                board[x][y]='X';
                return board;
            }
            int bombCnt=0;
            for(int i=0;i<8;++i){
                int newx=arrx[i]+x;
                int newy=arry[i]+y;
                if(0<=newx && newx<rows && 0<=newy && newy<cols && board[newx][newy]=='M'){
                    bombCnt++;
                }
            }
            if(bombCnt==0){
                board[x][y]='B';
                for(int i=0;i<8;++i){
                    int newx=arrx[i]+x;
                    int newy=arry[i]+y;
                    if(0<=newx && newx<rows && 0<=newy && newy<cols){
                        que.emplace(newx,newy);
                    }
                }
            }else{
                board[x][y]=bombCnt+'0';
            }
        }
        return board;
    }
};

Python代码

class Solution:
    # 广度优先搜索
    def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:
        rows,cols=len(board),len(board[0])
        visited=set()
        que=[(click[0],click[1])]
        while que:
            x,y=que.pop(0)
            if (x,y) in visited:
                continue
            visited.add((x,y))
            if board[x][y]=="M":
                board[x][y]="X"
                return board
            bombCnt=0
            for direct in [[-1,-1],[-1,1],[1,-1],[1,1],[1,0],[-1,0],[0,-1],[0,1]]:
                newX=direct[0]+x
                newY=direct[1]+y
                if 0<=newX<rows and 0<=newY<cols and board[newX][newY]=="M":
                    bombCnt+=1
            if bombCnt==0:
                board[x][y]="B"
                for direct in [[-1,-1],[-1,1],[1,-1],[1,1],[1,0],[-1,0],[0,-1],[0,1]]:
                    newX=direct[0]+x
                    newY=direct[1]+y
                    if 0<=newX<rows and 0<=newY<cols:
                        que.append((newX,newY))
            else:
                board[x][y]=str(bombCnt)
        return board





4.执行结果

在这里插入图片描述

posted @   Geek0070  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示