[LeetCode] 529. Minesweeper_ Medium_ tag: BFS

Let‘s play the minesweeper game (Wikipediaonline game)!

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.

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:

  1. If a mine (‘M‘) is revealed, then the game is over - change it to ‘X‘.
  2. If an empty square (‘E‘) with no adjacent mines is revealed, then change it to revealed blank (‘B‘) and all of its adjacent unrevealed squares should be revealed recursively.
  3. If an empty square (‘E‘) with at least one adjacent mine is revealed, then change it to a digit (‘1‘ to ‘8‘) representing the number of adjacent mines.
  4. Return the board when no more squares will be revealed.

Example 1:

Input: 

[[‘E‘, ‘E‘, ‘E‘, ‘E‘, ‘E‘],
 [‘E‘, ‘E‘, ‘M‘, ‘E‘, ‘E‘],
 [‘E‘, ‘E‘, ‘E‘, ‘E‘, ‘E‘],
 [‘E‘, ‘E‘, ‘E‘, ‘E‘, ‘E‘]]

Click : [3,0]

Output: 

[[‘B‘, ‘1‘, ‘E‘, ‘1‘, ‘B‘],
 [‘B‘, ‘1‘, ‘M‘, ‘1‘, ‘B‘],
 [‘B‘, ‘1‘, ‘1‘, ‘1‘, ‘B‘],
 [‘B‘, ‘B‘, ‘B‘, ‘B‘, ‘B‘]]

Explanation:

Example 2:

Input: 

[[‘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:

  1. The range of the input matrix‘s height and width is [1,50].
  2. The click position will only be an unrevealed square (‘M‘ or ‘E‘), which also means the input board contains at least one clickable square.
  3. The input board won‘t be a stage when game is over (some mines have been revealed).
  4. For simplicity, not mentioned rules should be ignored in this problem. For example, you don‘t need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares.

这一题乍一看好像蛮复杂的, 但实际上就是BFS, 只不过要注意的就是如果检测的点的周围有mine, 不需要将neighbor 再append进入queue, 其他的就是常规的BFS的操作, 然后看了discussion之后, 发现可以将其中部分code简化为一行, python果然是简洁的语言!

1. constraints

1) matrix [1,50] * [1, 50], cannot be empty

2) click will be ‘M‘ or ‘E‘, always valid

3) no ‘X‘ at beginning.

2. ideas

BFS:   T: O(m*n)   S: O(1) # change in place

1, if click == ‘M‘, change into "X" , return board

2. queue(init:[(orir, oric)]), visited(inti: set((orir, oric))), dirs

3. queue.popleft(), check neighbors , count number of ‘M‘, if >0, change into str(count), else "B" and queue.append(neigb) if neigb == ‘E‘ and not visited

4. return board

3. code

 1 class Solution:
 2     def Mine(self, board, click):
 3         lr, lc , orir, oric = len(board), len(board[0]), click[0], click[-1]
 4         if board[orir][oric] == ‘M‘:
 5             board[orir][oric] = ‘X‘
 6             return board
 7         queue, visited, dirs = collections.deque([(orir, oric)]), set((orir, oric)), [(0,1), (0,-1), (-1,0), (-1,-1), (-1,1), (1, -1), (1,0), (1,1)]
 8         while queue:
 9             pr, pc = queue.popleft()
10             count = 0
11             # visited.add((pr,pc)) # 不在这里加是因为会time limit 不符合, 因为还是会有重复的加入情况
12             for d1, d2 in dirs:
13                 nr, nc = pr + d1, pc + d2
14                 if 0<= nr < lr and 0<= nc < lc:
15                     if board[nr][nc] == ‘M‘:
16                         count += 1
17             if count == 0:
18                 board[pr][pc] = ‘B‘
19                 for d1, d2 in dirs:
20                     nr, nc = pr + d1, pc + d2
21                     if 0<= nr < lr and 0<= nc < lc:
22                         if board[nr][nc] == ‘E‘ and (nr, nc) not in visited:
23                             queue.append((nr, nc))
24                             visited.add((nr, nc)) # 所以visited加在这, 自行体会...
25         return board     

3.2  updated code(更简洁)

 1 lr, lc, orir, oric = len(board), len(board[0]), click[0], click[-1]
 2         if board[orir][oric] == ‘M‘:
 3             board[orir][oric] = ‘X‘
 4             return board
 5         queue, visited, dirs = collections.deque([(orir,oric)]), set((orir, oric)), [(0,1), (0,-1), (-1,0), (-1,-1), (-1,1), (1, -1), (1,0), (1,1)]
 6         while queue:
 7             pr, pc = queue.popleft()
 8             #visited.add((pr,pc))
 9             count = sum(board[pr + d1][pc + d2] == ‘M‘ for d1, d2 in dirs if 0 <= pr + d1 <lr and 0 <= pc + d2< lc)
10             board[pr][pc] = ‘B‘ if count == 0 else str(count)
11             if count == 0:
12                 for d1, d2 in dirs:
13                     nr, nc = pr + d1, pc + d2
14                     if 0 <= nr <lr and 0 <= nc < lc and board[nr][nc] == ‘E‘ and (nr, nc) not in visited:
15                         queue.append((nr,nc))
16                         visited.add((nr, nc))
17         return board

3.3 DFS, 但是本质一样.

 1 # DFS   T: O(m*n)  S: O(m*n)   # only difference between DFS and BFS is one use stack , the other use deque. so to the 2D array if can use DFS, usually can use BFS too.
 2         lr, lc, orir, oric = len(board), len(board[0]), click[0], click[-1]
 3         if board[orir][oric] == ‘M‘:
 4             board[orir][oric] = ‘X‘
 5             return board
 6         stack, visited, dirs = [(orir, oric)], set((orir, oric)), [(0,1), (0, -1), (1, -1), (1, 0), (1,1), (-1, -1), (-1, 0), (-1, 1)]
 7         while stack:
 8             pr, pc = stack.pop()
 9             count = sum(board[pr + d1][pc + d2]== ‘M‘ for d1, d2 in dirs if 0<= pr+d1 < lr and 0<= pc + d2 < lc)
10             if count > 0:
11                 board[pr][pc] = str(count)
12             else:
13                 board[pr][pc] = ‘B‘
14                 for d1, d2 in dirs:
15                     nr, nc = pr + d1, pc + d2
16                     if 0 <= nr < lr and 0 <= nc < lc and board[nr][nc] == ‘E‘ and (nr, nc) not in visited:
17                         stack.append((nr, nc))
18                         visited.add((nr, nc))
19         return board

4. test cases

题目上的两个cases

原文地址:https://www.cnblogs.com/Johnsonxiong/p/9256713.html

时间: 2024-10-31 09:11:00

[LeetCode] 529. Minesweeper_ Medium_ tag: BFS的相关文章

[LeetCode] 690. Employee Importance_Easy tag: BFS

You are given a data structure of employee information, which includes the employee's unique id, his importance value and his directsubordinates' id. For example, employee 1 is the leader of employee 2, and employee 2 is the leader of employee 3. The

[LeetCode] 130. Surrounded Regions_Medium tag: DFS

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A region is captured by flipping all 'O's into 'X's in that surrounded region. Example: X X X X X O O X X X O X X O X X After running your function, the bo

[LeetCode] 849. Maximize Distance to Closest Person_Easy tag: BFS

In a row of seats, 1 represents a person sitting in that seat, and 0 represents that the seat is empty. There is at least one empty seat, and at least one person sitting. Alex wants to sit in the seat such that the distance between him and the closes

[LeetCode] 126. Word Ladder II_Hard tag: BFS&amp;DFS

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: Only one letter can be changed at a time Each transformed word must exist in the word list. Note

Clone Graph leetcode java(DFS and BFS 基础)

题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and each n

Leetcode之广度优先搜索(BFS)专题-1162. 地图分析(As Far from Land as Possible)

BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree Level Order Traversal) 你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了.其中 0 代表海洋,1 代表陆地,你知道距离陆地区域最远的海洋区域是是哪一个吗?请返回该海洋区域到离它最近的陆地区域的距离. 我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0) 

Leetcode之广度优先搜索(BFS)专题-994. 腐烂的橘子(Rotting Oranges)

BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tree Level Order Traversal) 在给定的网格中,每个单元格可以有以下三个值之一: 值 0 代表空单元格: 值 1 代表新鲜橘子: 值 2 代表腐烂的橘子. 每分钟,任何与腐烂的橘子(在 4 个正方向上)相邻的新鲜橘子都会腐烂. 返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数.如果不可能,返回 -1. 示例 1: 输入:[[2,1,1],[1,1,0],[0,1,1

[LeetCode] 675. Cut Off Trees for Golf Event_Hard tag: BFS

You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-negative 2D map, in this map: 0 represents the obstacle can't be reached. 1 represents the ground can be walked through. The place with number bigger than

[LeetCode] 102. Binary Tree Level Order Traversal_Medium tag: BFS

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example:Given binary tree [3,9,20,null,null,15,7], 3 / 9 20 / 15 7 return its level order traversal as: [ [3], [9,20], [15,7] ]