1. 所有可能的路径
class Solution:
def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
def dfs(graph, result, path, root): #result 返回结果, path记录路径, root记录遍历到了第几个节点
if root == len(graph) - 1: #如果遍历到最后一个节点,记录结果并返回
result.append(path.copy())
return
for i in graph[root]: #遍历每个节点下一个能到的下一个节点
path.append(i) #path直接添加
dfs(graph, result, path, i) #dfs递归, 输入的root直接变成i,也就是当前遍历的下一个
path.pop() #回溯
result = []
path = [0] #初始化的时候path里已经有最初始的节点位置
root = 0 #起始节点为0
dfs(graph, result, path, root)
return result
实际上就是回溯算法,区别在于:之前做的回溯的题目一般是列表里面一个一个元素遍历,所以在递归的时候有一个start_index变量,控制选与不选当前元素。
而dfs搜索找下一个节点的时候,不用一个个遍历graph中的节点,而是只需要遍历当前节点能到达的节点,因为如果当前节点都到不了的节点,就没有必要往后遍历了。
因此递归的dfs的输入就变成了当前遍历的节点i
2. 岛屿数量
广搜 bfs版本
class Solution:
def __init__(self):
self.dir = [(0, 1), (1, 0), (0, -1), (-1, 0)]
self.count = 0
def bfs(self, grid, visited, x, y): #广搜函数定义
from collections import deque
queue = deque() #初始化队列
queue.append((x, y)) #加入起始节点
visited[x][y] = True #标记起始节点为已访问
while queue: #队列不为空进入循环
curx, cury = queue.popleft() #取头节点
for dx, dy in self.dir: #遍历四个方向
nextx ,nexty = curx + dx, cury + dy
if nextx < 0 or nextx >= len(grid) or nexty < 0 or nexty >= len(grid[0]): #越界就跳过
continue
if grid[nextx][nexty] == "0": #如果本题中是海水也跳过
continue
if not visited[nextx][nexty]: #把所有陆地标记为已访问
queue.append((nextx, nexty))
visited[nextx][nexty] = True
def numIslands(self, grid: List[List[str]]) -> int:
visited = [[False] * len(grid[0]) for _ in range(len(grid))] #初始化访问数组
for i in range(len(grid)):
for j in range(len(grid[0])): #遍历grid
if visited[i][j] == False and grid[i][j] == "1": #如果节点没被访问过以及是陆地
self.count += 1 #计数+1
self.bfs(grid, visited, i, j) #深搜一下把当前节点连通的所有陆地都标记为已访问
return self.count
3. 岛屿最大面积
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
def bfs(grid, visited, x, y):
from collections import deque
q = deque() #初始化队列
q.append((x, y)) #加入起点
visited[x][y] = True #标记已遍历起点
cnt = 1 #记录岛屿大小
direction = [(-1, 0), (0, -1), (1, 0), (0, 1)] #四个方向
while(q): #循环遍历队列中的节点
curx, cury = q.popleft() #取出第一个节点
for dx, dy in direction: #遍历四个方向
nextx, nexty = curx + dx, cury + dy
if nextx < 0 or nextx >= len(grid): #越界直接跳过
continue
if nexty < 0 or nexty >= len(grid[0]):
continue
if grid[nextx][nexty] == 0: #不是岛屿也直接跳过
continue
if not visited[nextx][nexty]: #是岛屿的部分
q.append((nextx, nexty)) #加入节点
visited[nextx][nexty] = True #标记为已访问
cnt += 1 #面积加1
return cnt #返回当前起点的岛屿大小
result = 0
visited = [[False] * len(grid[0]) for _ in range(len(grid))]
for i in range(len(grid)): #遍历网格
for j in range(len(grid[0])):
if not visited[i][j] and grid[i][j] == 1: #让每个是岛屿的节点并且没被访问过的点作为起点去BFS
cur = bfs(grid, visited, i, j) #记录当前节点为起点的岛屿大小
result = max(cur, result) #记录最大的岛屿大小
return result