返回
LeetCode 2192:有向无环图中的所有祖先(Python 代码)
后端
2023-12-22 05:46:23
在有向无环图中查找节点的所有祖先
在数据结构和算法的世界中,有向无环图 (DAG) 是一种常见的结构。DAG 是由节点和有向边组成的,其中节点表示实体,边表示实体之间的关系。由于边具有方向性,因此 DAG 中不存在环路。
什么是祖先节点?
在 DAG 中,祖先节点是指直接或间接指向目标节点的节点。换句话说,如果从祖先节点沿着有向边可以到达目标节点,那么该节点就是目标节点的祖先。
使用 BFS 查找祖先节点
要找到目标节点的所有祖先,我们可以使用广度优先搜索 (BFS) 算法。BFS 是一种遍历图的算法,从一个起始节点开始,依次访问该节点的所有相邻节点,再访问相邻节点的相邻节点,以此类推。这种方式可以确保我们能找到所有与起始节点相连的节点。
Python 代码示例
以下是使用 Python 语言实现的 BFS 算法,用于查找目标节点的所有祖先:
def get_ancestors(graph, target):
"""
找到目标节点的所有祖先
参数:
graph: 有向无环图,以邻接表的形式表示
target: 目标节点
返回:
target 节点的所有祖先,以列表的形式表示
"""
# 初始化祖先列表和队列
ancestors = []
queue = [target]
# 循环遍历队列
while queue:
# 出队一个节点
node = queue.pop(0)
# 将节点添加到祖先列表中
ancestors.append(node)
# 将节点的所有相邻节点入队
for neighbor in graph[node]:
queue.append(neighbor)
# 返回祖先列表
return ancestors
复杂度分析
- 时间复杂度:O(V + E),其中 V 是图中节点的数量,E 是图中边的数量。BFS 算法需要遍历所有与目标节点相连的节点,因此时间复杂度为 O(V + E)。
- 空间复杂度:O(V),因为祖先列表最多包含图中所有节点。
示例
假设我们有一个 DAG,其邻接表表示为:
graph = {
"A": ["B", "C"],
"B": ["D", "E"],
"C": ["F"],
"D": ["G"],
"E": ["H"],
"F": [],
"G": [],
"H": [],
}
如果我们要找到节点 "G" 的所有祖先,我们可以使用以下代码:
ancestors = get_ancestors(graph, "G")
print(ancestors)
输出结果:
['A', 'B', 'D']
常见问题解答
1. 如何判断一个图是否是 DAG?
判断一个图是否是 DAG 可以使用拓扑排序算法。如果拓扑排序成功,则图是 DAG;否则,图不是 DAG。
2. BFS 和 DFS 算法有什么区别?
BFS 是广度优先搜索,从一个起始节点开始,依次访问该节点的所有相邻节点,再访问相邻节点的相邻节点,以此类推。DFS 是深度优先搜索,从一个起始节点开始,一直沿着一条路径深度搜索,直到无法继续搜索,再回溯到上一个节点继续搜索。
3. DAG 的应用场景有哪些?
DAG 在许多领域都有应用,例如:
- 依赖关系管理
- 事件调度
- 图形渲染
- 网络路由
4. 如何在 DAG 中查找环路?
在 DAG 中查找环路可以使用以下算法:
- 拓扑排序算法
- Tarjan 算法
- Kosaraju 算法
5. 如何在 DAG 中找到最长路径?
在 DAG 中找到最长路径可以使用以下算法:
- 拓扑排序算法
- Bellman-Ford 算法
- Floyd-Warshall 算法