深度优先搜索的思想可以参考大佬的博客。
广度优先搜索的思想可以参考这位大佬的博客。
思路:有3条规则需要明确:规则1,点击的位置如果是地雷’M’,则将它改为’X’,游戏结束,直接返回。
如果点击的是空方块’E’,则计算其八个方向是否有地雷,(1)若有,规则2,对应修改为数字(‘1’到‘8’),(2)若无,规则3,当前格子修改为’B’,同时向’B’的周围(八个方向)开始扩展,遍历到的格子必须是未被挖出的空方块’E’。
注意
:当前格子为’B’时,才向周围搜索,如果当前格子为数字,是不向周围搜索的。
时间复杂度: O ( n m ) O(nm) O(nm), n m nm nm是整个二维字符矩阵的方块数,最差的情况就是每个方块遍历一遍。
class Solution:
directions = ((-1,0),(1,0),(0,-1),(0,1),(-1,-1),(-1,1),(1,-1),(1,1))
def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:
i = click[0]
j = click[1]
# 规则1,当点到的格子有雷时,直接将'M'替换成'X'
if board[i][j] == 'M':
board[i][j] = 'X'
elif board[i][j] == 'E':
Solution.dfs(board,i,j)
return board
# 当点到的格子是空方块'E',需要判断周围有无雷,有雷填数字,无雷填'B'
def dfs(board,i,j):
cnt = 0 #初始化雷的个数为0
for ni,nj in Solution.directions:
ni, nj = ni+i, nj+j
# 如果当前格子的相邻格子不存在,即下标越界了,则跳过,执行下一循环
if ni<0 or ni>=len(board) or nj<0 or nj>=len(board[0]):
continue
if board[ni][nj] == 'M':
cnt += 1
# 规则2,如果当前格子周围有雷,则填写数字
if cnt>0:
board[i][j] = str(cnt)
# 规则3,如果当前格子周围无雷,则填写'B'
else:
board[i][j] = 'B'
# 现在需要向'B'周围扩展,能够被扩展的条件是该格子必须为未挖出的空方块'E',该格子上有其他标志说明已经被扩展过了
for ni,nj in Solution.directions:
ni, nj = ni+i, nj+j
if ni<0 or ni>=len(board) or nj<0 or nj>=len(board[0]) or board[ni][nj]!='E':
continue
Solution.dfs(board,ni,nj)
//num为能打开的房间个数,若所有房间能被开锁,则num的大小应为房间个数
int num;
void dfs(int** rooms, int* roomsColSize, int* vis, int x){
vis[x] = true;
num++;
for(int i=0;i<roomsColSize[x];i++){
if(!vis[rooms[x][i]]){
dfs(rooms,roomsColSize,vis,rooms[x][i]);
}
}
}
//roomsColSize存储的是每列的尺寸
bool canVisitAllRooms(int** rooms, int roomsSize, int* roomsColSize){
int vis[roomsSize];
memset(vis,0,sizeof(vis));
num = 0;
dfs(rooms,roomsColSize,vis,0);
return num==roomsSize;
}
【深度优秀搜索】Python
class Solution:
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
def dfs(x: int):
vis.add(x)
nonlocal num
num += 1
for it in rooms[x]:
if it not in vis:
dfs(it)
vis = set()
num = 0
dfs(0)
n = len(rooms)
return num==n
【广度优先搜索】C语言
bool canVisitAllRooms(int** rooms, int roomsSize, int* roomsColSize) {
int vis[roomsSize], que[roomsSize];
memset(vis, 0, sizeof(vis));
int left = 0, right = 1, num = 0;
vis[0] = true;
que[0] = 0;
while (left < right) {
int x = que[left++];
num++;
for (int i = 0; i < roomsColSize[x]; i++) {
if (!vis[rooms[x][i]]) {
vis[rooms[x][i]] = true;
que[right++] = rooms[x][i];
}
}
}
return num == roomsSize;
}
【广度优先搜索】Python
class Solution:
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
n = len(rooms)
num = 0
vis = {0}
que = collections.deque([0])
while que:
x = que.popleft()
num += 1
for it in rooms[x]:
if it not in vis:
vis.add(it)
que.append(it)
return num == n
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/keys-and-rooms/solution/yao-chi-he-fang-jian-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。