返回

Python 解题思路,助你征服 LeetCode 685: 冗余连接 II

前端

理解问题背景

LeetCode 685 题旨在解决一个有向图中的冗余连接问题。给定一个有向图,其中一个节点被标记为根节点,你需要找到图中所有冗余连接,即那些连接了两个已经直接或间接相连的节点的边。

Python 代码实现

def findRedundantDirectedConnection(edges):
    # 使用邻接表存储有向图
    graph = defaultdict(list)
    # 存储每个节点的父节点
    parents = {}
    # 存储指向每个节点的所有边的集合
    edges_to_node = defaultdict(list)

    # 遍历边列表,构建邻接表和 parents 字典
    for u, v in edges:
        graph[u].append(v)
        parents[v] = u
        edges_to_node[v].append((u, v))

    # 寻找指向根节点的边
    start_edges = [edge for edge in edges if edge[1] == 1]
    # 寻找指向根节点的冗余边
    redundant_edge = None
    if len(start_edges) == 2:
        # 如果有两个指向根节点的边,则第一个边是冗余边
        redundant_edge = start_edges[0]
    elif len(start_edges) == 1:
        # 如果只有一个指向根节点的边,则寻找指向该边的冗余边
        redundant_edge = find_redundant_edge(graph, start_edges[0][0], parents, edges_to_node)

    # 如果没有找到冗余边,则寻找指向非根节点的冗余边
    if redundant_edge is None:
        redundant_edge = find_redundant_edge(graph, 1, parents, edges_to_node)

    return redundant_edge

# 寻找指向非根节点的冗余边
def find_redundant_edge(graph, node, parents, edges_to_node):
    # 使用深度优先搜索算法
    visited = set()
    stack = [node]

    while stack:
        # 弹出栈顶元素
        node = stack.pop()
        # 如果已经访问过该节点,则说明存在环
        if node in visited:
            # 找到导致环的边
            for edge in edges_to_node[node]:
                if edge[1] in visited:
                    return edge
        else:
            # 标记该节点为已访问
            visited.add(node)
            # 将该节点的邻居压入栈
            for neighbor in graph[node]:
                if neighbor not in visited:
                    stack.append(neighbor)

    return None

算法复杂度分析

  • 时间复杂度:O(V + E),其中 V 是节点的数量,E 是边的数量。
  • 空间复杂度:O(V + E),其中 V 是节点的数量,E 是边的数量。

结语

LeetCode 685 题是一道经典的有向图问题,通过使用 Python 语言和邻接表数据结构,我们可以高效地解决这个问题。希望这篇文章对大家有所帮助,也欢迎大家在评论区提出问题或分享你们的解题思路。