让我们一起来玩扫雷游戏!
给你一个大小为 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' ),表示相邻地雷的数量。
如果在此次点击中,若无更多方块可被揭露,则返回盘面。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minesweeper
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
题目要求点击一个方块时,若该方块周围(最多8个方块)都不是雷,则需要点击周围方块。
所以采用递归的方式点击。
构建递归函数void dfs(....)。需传递矩阵board信息和点击位置(x,y)。
1、检测位置是否合法。越界 或者 该位置已被点开,直接退出。
2、检测是否点到了地雷。是地雷则只需简单修改该位置的值,然后退出。
3、不是雷。获取周围有地雷个数num(构建一个新的函数实现)。
若num>0:周围有地雷,只需简单修改矩阵信息即可退出,不用点击周围的方块。
若num== 0:要递归点击周围的方块。遍历周围8个格子,依次调用dfs。
//获取周围地雷个数
int get_bombs(char** board,int m,int n,int x,int y){
int new_x,new_y;
int num = 0;
for(int i = -1;i<2;i++)
for(int j = -1 ;j<2;j++){
if(i==0 && j==0)
continue;
new_x = x + i;
new_y = y + j;
if(new_x < 0 || new_x >= m || new_y < 0 || new_y >= n) //出界了
continue;
if(board[new_x][new_y] == 'M')
num++;
}
return num;
}
//递归点击
void dfs(char**board,int m, int n,int x,int y){
//该位置已被点击,直接退出
if(board[x][y] != 'M' && board[x][y] != 'E')
return board;
//点到地雷
if(board[x][y] == 'M'){
board[x][y] = 'X';
return;
}
//不是地雷
int num = get_bombs(board,m,n,x,y); // 获取x,y周围地雷个数
if(num > 0){
board[x][y] = '0' + num;
return;
}
//周围没雷,需递归点击周围每个格子
board[x][y] = 'B';
int new_x,new_y;
for(int i = -1;i<2;i++)
for(int j = -1;j<2;j++){
if(i == 0 && j == 0)
continue;
new_x = x + i;
new_y = y + j;
if(new_x < 0 || new_x >= m || new_y < 0 || new_y >= n) //出界了
continue;
dfs(board,m,n,new_x,new_y);
}
return;
}
char** updateBoard(char** board, int boardSize, int* boardColSize, int* click, int clickSize, int* returnSize, int** returnColumnSizes){
int m = boardSize,n = boardColSize[0];
*returnSize = boardSize;
(*returnColumnSizes) = malloc(sizeof(int)*m);
for(int i =0;i<m;i++)
(*returnColumnSizes)[i] = boardColSize[i];
if(clickSize < 2)
return board;
//点击位置不对
int x = click[0],y = click[1];
if(x < 0 || x >= m || y < 0 || y >= n)
return board;
//点击(x,y)处
dfs(board,m,n,x,y);
return board;
}
运行结果如下: