Let's play the minesweeper game (Wikipedia),online game)!java
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.git
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:ide
Example 1:this
Input:spa
[['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'M', 'E', 'E'], ['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E']]
Click : [3,0]code
Output:blog
[['B', '1', 'E', '1', 'B'], ['B', '1', 'M', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', 'B', 'B', 'B']]
Explanation:递归
Example 2:游戏
Input:ip
[['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:
玩过扫雷游戏的同窗应该熟悉扫雷的规则,这题的目标在于模拟扫雷游戏,它给了一块已经完成一部分操做的扫雷面板,而且输入了下一步点击的位置。要求输出执行此次点击后面板的最新状态。
其中M表示隐藏的雷,X表示被点开的雷。E表示未被点开的空格,B表示被点开的空格,数字1到8表示距离该格子一圈一共有几个雷。
当玩家点击了格子后,一共有三种状况
这是一道典型的经过广搜或是深搜解决的题目。广搜即以雷区为中心,每次向外搜索一圈,深搜则是搜索到全是雷区为止。广搜代码以下:
public char[][] updateBoard(char[][] board, int[] click) { char clickValue = board[click[0]][click[1]]; if (clickValue == 'M') { board[click[0]][click[1]] = 'X'; } else if (clickValue == 'E') { //广度优先遍历 Queue<int[]> queue = new LinkedList<>(); queue.offer(click); //8个方向 int[][] directions = new int[][]{ {0, 1}, {0, -1}, {-1, 0}, {1, 0}, {-1, -1}, {-1, 1}, {1, 1}, {1,-1} }; while (!queue.isEmpty()) { int[] tmpClick = queue.poll(); int countOfMine = 0; List<int[]> emptyCells = new ArrayList<>(); for (int\[] direction : directions) { int rowIndex = direction[0] + tmpClick[0]; int columnIndex = direction[1] + tmpClick[1]; if (rowIndex < 0 || rowIndex >= board.length || columnIndex < 0 || columnIndex >= board[0].length) { continue; } if (board[rowIndex][columnIndex] == 'M') { countOfMine++; } else if (board[rowIndex][columnIndex] == 'E') { emptyCells.add(new int[]{rowIndex, columnIndex}); } } if (countOfMine == 0) { board[tmpClick[0]][tmpClick[1]] = 'B'; //防止重复遍历,先将其置为B for (int[] emptyCell : emptyCells) { board[emptyCell[0]][emptyCell[1]] = 'B'; } queue.addAll(emptyCells); } else { board[tmpClick[0]][tmpClick[1]] = (char)('0' + countOfMine); } } } return board; }
深搜代码以下:
public char[][] updateBoard2(char[][] board, int[] click) { int m = board.length, n = board[0].length; int row = click[0], col = click[1]; if (board[row][col] == 'M') { // Mine board[row][col] = 'X'; } else { // Empty // Get number of mines first. int count = 0; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (i == 0 && j == 0) continue; int r = row + i, c = col + j; if (r < 0 || r >= m || c < 0 || c < 0 || c >= n) continue; if (board[r][c] == 'M' || board[r][c] == 'X') count++; } } if (count > 0) { // If it is not a 'B', stop further DFS. board[row][col] = (char)(count + '0'); } else { // Continue DFS to adjacent cells. //递归的进行深度优先遍历 board[row][col] = 'B'; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { if (i == 0 && j == 0) continue; int r = row + i, c = col + j; if (r < 0 || r >= m || c < 0 || c < 0 || c >= n) continue; if (board[r][c] == 'E') updateBoard(board, new int[] {r, c}); } } } } return board; }