📌  相关文章
📜  检查基于给定条件从数组构造的图是否包含循环(1)

📅  最后修改于: 2023-12-03 14:55:45.244000             🧑  作者: Mango

检查基于给定条件从数组构造的图是否包含循环

简介

在一些算法问题中,我们需要构造一个图来解决问题。而有时这个图是由给定的数组构造而成的,比如题目中给出的每个元素表示节点之间的连边关系。但是这样构造出来的图是否包含循环是不确定的,所以我们需要编写一个函数来检查图是否包含循环。

解题思路

我们可以使用深度优先搜索(DFS)来判断图中是否有循环。

具体步骤如下:

  1. 定义一个 visited 数组,表示该节点是否被访问过,首先将所有节点都初始化为未访问状态。
  2. 从某一个节点开始进行 DFS 遍历,可以从起点开始遍历,也可以从每个未访问过的节点开始遍历。
  3. 当遍历到一个节点时,将其置为已访问状态,并查找该节点所连的其他节点。
  4. 如果该节点所连的其他节点已经被访问过,则说明存在循环,返回 True。
  5. 如果该节点所连的其他节点未被访问过,则以这些节点为起点继续进行 DFS 遍历。
  6. 直到遍历完所有节点都无法找到循环,则返回 False。
代码示例

下面是一个 Python 代码示例,实现了上述思路:

from typing import List

def has_cycle(graph: List[List[int]]) -> bool:
    def dfs(v):
        visited[v] = 1
        for neighbor in graph[v]:
            if visited[neighbor] == 1:
                return True
            elif visited[neighbor] == 0 and dfs(neighbor):
                return True
        visited[v] = -1
        return False
        
    n = len(graph)
    visited = [0] * n  # 0 表示未访问,1 表示正在访问,-1 表示访问完成
    for i in range(n):
        if visited[i] == 0 and dfs(i):
            return True
    return False

其中,graph 是一个二维数组,表示图的连边情况,visited 数组用来记录每个节点的访问状态。

上述代码中,局部函数 dfs 实现了 DFS 的遍历过程,visited[v] = 1 表示将节点 v 标记为正在访问,遍历完节点的所有邻居后,将节点 v 标记为访问完成。如果存在某个邻居节点 neighbor 已经被访问过(即 visited[neighbor] == 1),则说明存在循环,直接返回 True;否则,如果邻居节点 neighbor 未被访问过(即 visited[neighbor] == 0),则以 neighbor 为起点继续进行 DFS 遍历。

最后,在主函数中遍历所有节点,以每个未访问过的节点为起点进行 DFS 遍历,如果存在循环,则返回 True;否则,返回 False。