[Dfs] B013_ Minesweeper (dfs | bfs)

One, Title Description

给定一个代表游戏板的二维字符矩阵。 'M' 代表一个未挖出的地雷,'E' 代表一个未挖出的空方块,
'B' 代表没有相邻(上,下,左,右,和所有4个对角线)地雷的已挖出的空白方块,
数字('1''8')表示有多少地雷与这块已挖出的方块相邻,
'X' 则表示一个已挖出的地雷。

现在给出在所有未挖出的方块中('M'或者'E')的下一个点击位置(行和列索引),
根据以下规则,返回相应位置被点击后对应的面板:

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

Second, the problem solution

Method One: dfs

More information on the topic, they may wish to split:

  • 'M': no ​​dig mines
  • 'X': being dug out of mines, met representatives of the game is over X.
  • 'E': an unknown box.
  • 'B': a box of eight directions are sure there are no mines.
  • click [0]: Step 1 abscissa game.
  • click [1]: game ordinate Step 1.

algorithm

  • If the current position is not mines M, the temporarily marked as B, and then determine whether the distance between the outer mines 8 M direction current position of the step 1, there will be marked with a number of overlay marks countM mines B.
  • Otherwise, the location of mines labeled X can be, because there is only one explanation smear landmine M.
int m, n;
private static int[][] dir = {
  {-1, 0}, {1, 0},
  {0, -1}, {0, 1},
  {-1, -1},{-1, 1},
  {1, -1}, {1, 1},
};
public char[][] updateBoard(char[][] grid, int[] click) {
  m = grid.length;
  n = grid[0].length;
  dfs(grid, click[0], click[1]);
  return grid;
}
//深搜
private void dfs(char[][] grid, int x, int y) {
  if (!inArea(x, y))
      return;
  if (grid[x][y] == 'M') {
      grid[x][y] = 'X';
  }else if (grid[x][y] == 'E') {
    grid[x][y] = 'B';
    int countM = countM(grid, x, y);
    if (countM > 0) {
      grid[x][y] = (char) (countM + '0');
    }else {
      for (int i = 0; i < 8; i++) {
        int newX = x + dir[i][0];
        int newY = y + dir[i][1];
        dfs(grid, newX, newY);
      }
    }
  }
}
//统计8个方向的地雷数量
private int countM(char[][] grid, int x, int y) {
  int count = 0;
  for (int i = 0; i < 8; i++) {
    int newX = x + dir[i][0];
    int newY = y + dir[i][1];
    if (inArea(newX, newY) && grid[newX][newY] == 'M') {
      count++;
    }
  }
  return count;
}
private boolean inArea(int x, int y) {
  return x >= 0 && x < m && y >= 0 && y < n;
}

Complexity Analysis

  • time complexity: O ( m × n ) O(m × n)
  • Space complexity: O ( m × n ) O(m × n)

Method Two: bfs

No matter what way to solve this problem, in its essence is to traverse the entire grid, just traversed a different way, but the main logic is the same.

int m, n;
private static int[][] dir = {
	{-1, 0}, {1, 0},
	{0, -1}, {0, 1},
	{-1, -1},{-1, 1},
	{1, -1}, {1, 1},
};
public char[][] updateBoard(char[][] grid, int[] click) {
  m = grid.length;
  n = grid[0].length;
  Queue<Pos> queue = new LinkedList<>();
  queue.add(new Pos(click[0], click[1]));

  while (!queue.isEmpty()) {
    Pos pos = queue.poll();
    if (grid[pos.x][pos.y] == 'E') {
        grid[pos.x][pos.y] = 'B';
        int count = countM(grid, pos.x, pos.y);
        if (count > 0) {
        	grid[pos.x][pos.y] = ((char) (count + '0'));
        } else {
            for (int i = 0; i < 8; i++) {
                int newX = pos.x + dir[i][0];
                int newY = pos.y + dir[i][1];
                if (inArea(newX, newY)) {
                    queue.add(new Pos(newX, newY));
                }
            }
        }
    } else if (grid[pos.x][pos.y] == 'M')
        grid[pos.x][pos.y] = 'X';
  }
  return grid;
}

private boolean inArea(int x, int y) {
  return x >= 0 && x < m && y >= 0 && y < n;
}
private int countM(char[][] grid, int x, int y) {
  int count = 0;
  for (int i = 0; i < 8; i++) {
      int newX = x + dir[i][0];
      int newY = y + dir[i][1];
      if (inArea(newX, newY) && grid[newX][newY] == 'M') {
          count++;
      }
  }
  return count;
}

class Pos {
  int x, y;
  public Pos(int _x, int _y) {
      x = _x;
      y = _y;
  }
}

Complexity Analysis

  • time complexity: O ( m × n ) O(m × n)
  • Space complexity: O ( m × n ) O(m × n)
Published 495 original articles · won praise 105 · views 30000 +

Guess you like

Origin blog.csdn.net/qq_43539599/article/details/104783764