学习总结
学习内容
课程内容
深度优先搜索、广度优先搜索
深度优先搜索算法(Depth-First-Search),不撞南墙不回头。以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点;当没有未访问过的顶点时,则回到上一个顶点,继续试探访问别的顶点,直到所有的顶点都被访问。沿着某条路径遍历直到末端,然后回溯,再沿着另一条进行同样的遍历,直到所有的顶点都被访问过为止。
广度优先搜索(Breadth First Search, BFS),层层递进。以一个未被访问过的顶点作为起始顶点,访问其所有相邻的顶点,然后对每个相邻的顶点再访问它们相邻的未被访问过的顶点,直到所有顶点都被访问过,遍历结束。
代码模板
迭代实现:
深度优先搜索,堆栈实现;dfs=栈,压栈,出栈
广度优先搜索,队列实现;bfs=队列,入队列,出队列
DFS 代码模板:
递归实现:
#递归前处理
visited = set() # 节点是否被访问
def dfs(node,visited):
# 递归终止条件
if node in visited: # 是否被访问
return
# 递归到下一层前处理(当前层处理)
visited.add(node)
# 其它处理
# 递归到下一层
for next_node in node.children():
if not next_node in visited:
dfs(next_node, visited)
# 递归下层次返回后处理
迭代实现:
dfs=栈,压栈,出栈
def dfs(node,visited):
if tree.root is None:
return []
# 迭代前处理
visited, stack = [], [tree.root] # 辅助栈 压栈
# 迭代终止条件
while stack:
# 迭代
node = stack.pop() # 出栈
visited.add(node) # 标记访问
rocess (node) # 当前节点处理
nodes = generate_related_nodes(node) # 生成相关节点
stack.push(nodes) # 压栈
# 迭代后处理
BFS 代码模板:
迭代实现:
bfs=队列,入队列,出队列
def bfs(graph, start, end):
# 迭代前处理
queue = [] # 辅助队列
queue.append([start]) # 入队列
visited.add(node) # 标记访问
# 迭代终止条件
while queue:
# 迭代
node = queue.pop(0) # 出队列
visited.add(node) # 标记访问
rocess (node) # 当前节点处理
nodes = generate_related_nodes(node) # 生成相关节点
queue.push(nodes) # 入队列
# 迭代后处理
二分查找的实现、特性及实战题目解析
二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
二分查找代码模板:
left, right = 0, len(array) - 1
while left <= right:
# mid = (left + right) / 2
mid = low + (high-low)/2
if array[mid] == target:
# 找到目标
break or return result
elif array[mid] < target:
left = mid + 1
else:
right = mid - 1
作业,使用二分查找,寻找一个半有序数组[4, 5, 6, 7, 0, 1, 2]中间无序的地方
暴力法
中间无序的地方,其左右两边必然一个为单调递增,一个为单调递减
遍历半有序数组元素,然后对元素(n 下标)向前探(n-1)向后探(n+1)判断其单调性是否一致
二分查找
def search(nums: List[int]):
left, right = 0, len(nums)-1
while left < right:
# mid = left + (right - left)//2
mid = left + (right - left)>>1
# 判断 mid 位于哪里
if nums[mid] > nums[right]:
# 无序的地方 位于 mid 和 right 之间
left = mid + 1
else:
# 无序的地方 位于 left 和 mid 之间
right = mid - 1
return left