广度优先搜索(BFS)跟深度优先搜索(DFS)
两种搜索方法都是对二或以上维数据进行遍历搜索,按照人的思维可以按照深度优先,还是广度优先的规律来避免重复扫荡某个点。将这种规律赋给计算机去执行就是广度优先搜索跟深度优先搜索。
广度优先会采用一维数据结构例如队列来将某一层的数据存储,循环队列内元素来查找下一层数据,即一层层往更深的层级搜索。
深度优先会定义一个截止条件例如:找到空,在没有遇到空的时候一直往下查找。查找到空之后就去回溯,直到找到另一条没有被访问的路径,然后依上往下查找。
广度优先搜索
- 从根节点出发。
- 找到根节点下的子节点存入队列中,
- 在从队列中的子节点找到子节点的子节点添加进栈内
- 依次往下循环。
- 直至队列为空,则访问结束。
代码模版
def BFS(graph,start,end):
queue=[]
queue.append([start])
visited.add(start)
while queue: # clear the queue
node=queue.pop() # pop one node
visited.add(node) # add to visited for graph
process(node) # a function to process node
nodes=generate_related_nodes(node) # find the next nodes and the nodes not in visited
queue.push(node) # push nodes to queue
深度优先搜索
- 从根节点出发。
- 找寻根节点的一条路径终点。
- 回溯直至找到另一条没有被访问的节点,查找路径的终点。
- 递归第三步。
- 直至递归结束。
代码模版
一般深度优先
visited=set()
def DFS(node,visited):
visited.add(node)
# process current node
process(node)
for next_node in node.children():
if not next_node in visited:
DFS(next_node,visited)
在递归中是使用了栈的概念的,所以可以使用栈来进行深度优先。
def DFS(self,tree):
if tree.root is None :
return []
visited,stack=set(),[tree.root]
while stack:
node = stack.pop()
visited.add(node)
proecess(node)
node=generate_related_nodes(node)
stack.push(nodes)
实战题目
1. 二叉树的层序遍历
Leetcode 102
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
思路1:
- BFS
- 多循环一层queue 返回 层级list
- 将多层级list 相加即可
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root :
return []
queue=[root]
res=[]
while queue:
current_queue=[]
queue_size=len(queue)
for _ in range(queue_size):
node = queue.pop(0) #队列特性
current_queue.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(current_queue)
return res
思路2:
- DFS
- 每递归一层带入自己的层级信息,
- append到对应层级的二维数组内。
- 递归结束数据也添加结束。
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root :
return []
self.result=[]
self.dfs(root,0)
return self.result
def dfs(self,node,level):
if not node:
return
if len(self.result)<level+1:
self.result.append([])
self.result[level].append(node.val)
self.dfs(node.left,level+1)
self.dfs(node.right,level+1)
2. 二叉树的最大最小深度
思路1:
- DFS
- 定义最大最小深度。dfs带入层级信息,
- 每次dfs更新最大层级,
- 每次dfs 判断是否没有子节点,若没有更新最小深度
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root:
return 0
self.max_depth=0
self.min_depth=10**5
def dfs(node,level):
self.max_depth=max(self.max_depth,level)
if not node:
return
if not node.right and not node.left:
self.min_depth=min(level,self.min_depth)
dfs(node.left,level+1)
dfs(node.right,level+1)
dfs(root,0)
return self.min_depth +1
思路2:
- bfs
- 最小深度判断第一次出现是否没有子节点
- 最大深度就是底层。