力扣:扫雷游戏
题目描述
给定一个代表游戏板的二维字符矩阵。 'M' 代表一个未挖出的地雷,'E' 代表一个未挖出的空方块,'B' 代表没有相邻(上,下,左,右,和所有4个对角线)地雷的已挖出的空白方块,数字('1' 到 '8')表示有多少地雷与这块已挖出的方块相邻,'X' 则表示一个已挖出的地雷。
现在给出在所有未挖出的方块中('M'或者'E')的下一个点击位置(行和列索引),根据以下规则,返回相应位置被点击后对应的面板:
- 如果一个地雷('M')被挖出,游戏就结束了- 把它改为 'X'。
- 如果一个没有相邻地雷的空方块('E')被挖出,修改它为('B'),并且所有和其相邻的未挖出方块都应该被递归地揭露。
- 如果一个至少与一个地雷相邻的空方块('E')被挖出,修改它为数字('1'到'8'),表示相邻地雷的数量。
- 如果在此次点击中,若无更多方块可被揭露,则返回面板。
题意明了,直接上代码
class Solution { public char[][] updateBoard(char[][] board, int[] click) { int x = click[0] , y = click[1]; //如果所点击的点正好是雷,直接修改为 X 返回,反之 遍历周围的 8 个顶点 //但如果周围没有雷,修改当前格子为 B ,返回 if(board[x][y] == 'M'){ board[x][y] = 'X'; } else { dfs(board , x , y); } return board; } public void dfs(char[][] board , int x , int y){ // 左,左上,上,右上,右,右下,下,左下 8个方向 int[] dx = {0 , -1 , -1 , -1 , 0 , 1 , 1 , 1}; int[] dy = {-1 , -1 , 0 , 1 , 1 , 1 , 0 , -1}; //先统计一下当前点周围有多少颗雷 int cnt = 0; for(int i = 0 ; i < 8 ; i ++){ int nx = x + dx[i]; int ny = y + dy[i]; if(nx < 0 || nx >= board.length || ny < 0 || ny >= board[0].length) continue; //越界 if(board[nx][ny] == 'M') cnt ++; } if (cnt > 0) { board[x][y] = (char)(cnt + '0'); return; } //如果周围没有雷,设置为 B board[x][y] = 'B'; for(int i = 0 ; i < 8 ; i ++){ int nx = dx[i] + x; int ny = dy[i] + y; if(nx < 0 || nx >= board.length || ny < 0 || ny >= board[0].length || board[nx][ny] != 'E') continue; //越界, dfs(board , nx , ny); } } }