目录
一、栈和深度优先搜索
树的遍历:https://blog.csdn.net/qq_39478403/article/details/107329233
参考文献:https://leetcode-cn.com/leetbook/read/queue-stack/k3beh/
二、栈和 DFS
参考文献:https://leetcode-cn.com/leetbook/read/queue-stack/gro21/
三、DFS - 模板 I
// Java
/*
* Return true if there is a path from cur to target.
*/
boolean DFS(Node cur, Node target, Set<Node> visited) {
return true if cur is target;
for (next : each neighbor of cur) {
if (next is not in visited) {
add next to visted;
return true if DFS(next, target, visited) == true;
}
}
return false;
}
参考文献:https://leetcode-cn.com/leetbook/read/queue-stack/gp5a7/
三、岛屿数量
3.1 题目要求
3.2 解决过程
法一:BFS 迭代实现。沿竖直和水平方向遍历输入矩阵,每发现一个陆地 (标号1),就对其进行 BFS,并将可由 BFS 访问/搜索到的陆地都置为已访问/已搜索 (标号0) 以表示属于同一个岛屿,且因为已访问/已搜索而不必在后续过程中再次访问/搜索 (意为不会访问同一个节点两次)。空间复杂度 O(n),时间复杂度 O(n)。
2020/09/02 - 70.26% (80ms)
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
land_nums = 0 # 岛屿数量
for row in range(len(grid)): # 遍历行
for col in range(len(grid[0])): # 遍历列
if grid[row][col] == '1': # 发现陆地
land_nums += 1 # 岛屿数量 +1
grid[row][col] = '0' # 将已访问/已探索的陆地置为 0, 以后便不必再重复访问/搜索
# 对已发现陆地通过 BFS 扩张/辐射, 将与之相邻的陆地都标记为已访问/已探索状态
land_positions = collections.deque() # 内置双端队列, 保存已访问/已探索相邻陆地坐标
land_positions.append([row, col]) # 当前已访问/已探索陆地坐标入队
while len(land_positions) > 0: # 只要当前队列中还保存有已访问/已探索陆地坐标
x, y = land_positions.popleft() # 出队探索
for new_x, new_y in [[x, y+1], [x, y-1], [x+1, y], [x-1, y]]: # 向 4 个方向扩张/辐射
# 判断有效性, 要求是坐标界限范围内的陆地
if (0 <= new_x < len(grid)) and (0 <= new_y < len(grid[0])) and (grid[new_x][new_y] == '1'):
grid[new_x][new_y] = '0' # 因为可由 BFS 访问到, 故属同一块岛,将其置 0 代表已访问/已探索
land_positions.append([new_x, new_y]) # 已访问/已探索陆地坐标入队
return land_nums
法一改:BFS 迭代实现 - 函数封装。空间复杂度 O(n),时间复杂度 O(n)。
2020/09/02 - 70.26% (80ms)
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
from collections import deque # 双端队列
if not grid:
return 0
row = len(grid) # 行数
col = len(grid[0]) # 列数
cnt = 0 # 岛屿数
def bfs(i, j):
queue = deque() # 保存已访问/已探索的陆地队列
grid[i][j] = "0" # 将已发现的陆地置为已访问/已探索状态 0
queue.appendleft((i, j)) # 已发现陆地坐标入队
while queue: # 只要队列中还有坐标
i, j = queue.pop() # 弹出一个坐标
for x, y in [[-1, 0], [1, 0], [0, -1], [0, 1]]: # 向周围 4 个方向以单位距离搜索
tmp_i = i + x
tmp_j = j + y
# 若在范围内发现新陆地
if (0 <= tmp_i < row) and (0 <= tmp_j < col) and (grid[tmp_i][tmp_j] == "1"):