📜  门| GATE-CS-2017(套装2)|问题 22(1)

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

门| GATE-CS-2017(套装2)|问题 22

简介

问题 22 是 GATE-CS-2017 套装中的一道编程问题。这道问题旨在测试程序员对于数据结构和算法的理解和应用能力。问题要求实现一个程序,以检测给定的有向图是否存在环。

题目描述

给定一个含有 n 个节点的有向图,用邻接矩阵表示。请实现一个函数 isCyclic 来检测该图是否存在环。

函数签名
def isCyclic(graph: List[List[int]]) -> bool:
    pass
输入
  • graph: 一个 n x n 的二维列表,表示有向图的邻接矩阵。graph[i][j] 的值为 1 表示节点 i 到节点 j 存在一条边,值为 0 表示不存在。
输出
  • 返回一个布尔值,表示给定的图是否存在环。存在环返回 True,否则返回 False
示例
graph = [[0, 1, 0, 0],
         [0, 0, 1, 0],
         [0, 0, 0, 1],
         [1, 0, 0, 0]]
         
isCyclic(graph)
解题思路

我们可以使用深度优先搜索(DFS)来解决这个问题。从任意一个节点开始进行 DFS,每次遇到一个节点,我们标记该节点为"正在访问中",然后递归访问它的邻居节点。如果在这个递归访问过程中,我们又遇到了正在访问中的节点,说明存在环。如果遇到了已经访问完成的节点,我们则停止访问该路径。

具体步骤如下:

  1. 创建一个访问列表 visited 来记录节点的访问状态,初始值为 False。
  2. 创建一个递归函数 dfs,接受一个节点索引作为参数。
  3. dfs 函数中,将当前节点标记为正在访问中(将 visited[node] 设为 True)。
  4. 递归访问当前节点的邻居节点,如果邻居节点已经在访问中,则表示存在环,返回 True。
  5. 当递归返回时,将当前节点标记为已访问完成(将 visited[node] 设为 False)。
  6. 在主函数 isCyclic 中,遍历所有节点的访问状态,如果存在节点未被访问过,则调用 dfs 函数,并检查返回值是否为 True,是则返回 True。
  7. 如果遍历完所有节点后没有发现环,返回 False。
实现代码
from typing import List

def isCyclic(graph: List[List[int]]) -> bool:
    n = len(graph)
    visited = [False] * n
    
    def dfs(node: int) -> bool:
        visited[node] = True
        
        for neighbor in range(n):
            if graph[node][neighbor] == 1:
                if visited[neighbor] == True:
                    return True
                if dfs(neighbor) == True:
                    return True
        
        visited[node] = False
        return False
    
    for node in range(n):
        if visited[node] == False:
            if dfs(node) == True:
                return True
    
    return False
复杂度分析
  • 时间复杂度:O(V^2),其中 V 为节点数,因为我们需要遍历每个节点并递归地遍历它的邻居节点。
  • 空间复杂度:O(V),我们使用额外的 visited 列表来存储访问状态。

希望本文对您理解问题 22 有所帮助。如有任何疑问,请随时提问。