学习与参考资料:
[1] 2013王道论坛计算机考研机试指南
[2] DFS和BFS讲解及Leetcode刷题小结(1)(JAVA)
[3] DFS和BFS讲解及Leetcode刷题小结(2)(JAVA)
LC200. Number of Islands
from collections import deque
def dfs(grid,x,y):
if 0<=x<len(grid) and 0<=y<len(grid[0]) and grid[x][y]=="1":
grid[x][y]=0 # 将访问之后的陆地变成水,后面便不会再去访问了,省去了记录访问信息的数组
dfs(grid,x-1,y)
dfs(grid,x+1,y)
dfs(grid,x,y-1)
dfs(grid,x,y+1)
# 也可以用bfs
def bfs(grid, x, y):
queue = deque()
queue.append((x, y))
grid[x][y] = '0' # 将访问之后的陆地变成水,后面便不会再去访问了,省去了记录访问信息的数组
while queue:
directions = [(0,1), (0,-1), (-1,0), (1,0)]
x, y = queue.popleft()
for d in directions:
nx, ny = x + d[0], y + d[1]
if 0<=nx<len(grid) and 0<=ny<len(grid[0]) and grid[nx][ny] == '1':
queue.append((nx, ny))
grid[nx][ny] = '0' # 将访问之后的陆地变成水
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
if len(grid)==0:
return 0
cnt=0
for x in range(len(grid)):
for y in range(len(grid[0])):
if grid[x][y]=="1":
# bfs(grid,x,y)
dfs(grid,x,y)
cnt+=1
return cnt
题目链接:79. Word Search
class Solution:
def dfs(self, board, visited, x, y, word, k):
"""
整体逻辑是:检查与访问 + 递归与回溯
1、检查位置合法性与是否已经访问过
2、访问该位置,如果已经能判断结果则返回
3、否则,将当前位置设为已访问,对于每个方向的下个位置继续使用dfs
4、若某个方向成功到达终点则返回结果,若所有方向都失败,则回溯
"""
# 如果位置不合法或已经访问过
if not (0 <= x < len(board) and 0 <= y < len(board[0])) or visited[x][y]:
return False
if board[x][y] != word[k]: # 访问当前位置,如果不符合预期,返回False(剪枝)
return False
if board[x][y] == word[k] and k == len(word) - 1: # # 如果该位置符合预期且已经是终点(最后一个单词)
return True
visited[x][y] = True # 递归前先设置当前位置已经访问
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for d in directions: # 对每一个方向继续dfs
nx, ny = x + d[0], y + d[1]
if self.dfs(board, visited, nx, ny, word, k + 1): # 递归检查下个位置
return True # 如果成功到达终点,则返回True
# 如果所有方向dfs都失败,则将当前位置设为未访问过,可以让其他方案经过该位置
visited[x][y] = False
return False
def exist(self, board: List[List[str]], word: str) -> bool:
m = len(board)
n = len(board[0])
for x in range(m):
for y in range(n):
# 遍历每一个位置,如果符合起点要求则开始使用dfs回溯
if board[x][y] == word[0]:
# 每个起点使用一个全新的visited数组
visited = [[False] * n for _ in range(m)]
if self.dfs(board, visited, x, y, word, 0):
return True
return False
1219. 黄金矿工
class Solution:
def dfs(self, grid, seen, x, y):
if not (0 <= x < len(grid) and 0 <= y < len(grid[0])) or grid[x][y] == 0 or (x, y) in seen:
return 0
reward = grid[x][y]
seen.add((x, y))
max_direction_reward = 0
for d in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
nx, ny = x + d[0], y + d[1]
re = self.dfs(grid, seen, nx, ny)
if re > max_direction_reward:
max_direction_reward = re
seen.remove((x, y))
return reward + max_direction_reward
def getMaximumGold(self, grid: List[List[int]]) -> int:
max_reward = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
reward = self.dfs(grid, set(), i, j)
if reward > max_reward:
max_reward = reward
return max_reward