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; }