📜  | |第 42 题(1)

📅  最后修改于: 2023-12-03 15:35:50.664000             🧑  作者: Mango

| | 第 42 题介绍

题目描述

在一个有向图中,你总共有 n 个节点。你被赋予一个二维数组 graph,其中 graph[i] 是一个数组,表示 i 接到的所有节点的下标。

请你返回若干个长度为 n 的路径,其中每个路径都由从节点 0 到节点 n-1 的所有节点组成。答案可以按任意顺序返回。当不存在从节点 0 到节点 n-1 的路径时,返回一个空列表。

示例

输入:graph = [[1,2],[3],[3],[4],[]]

输出:[[0,1,3,4],[0,2,3,4]]

解释:两条路径 0 -> 1 -> 3 -> 4 和 0 -> 2 -> 3 -> 4

解题思路

可以使用 DFS 或 BFS 解题,本篇介绍使用 BFS 解题。首先将起点 0 加入队列中,queue 存储的是节点下标。在队列不为空的时候,每次从队首取出一个节点,遍历它所有可以访问到的节点,如果该节点没有被访问过,就标记为 visited,存储它的路径,加入队列。

解题步骤
  1. 根据 graph 数组构建一个邻接表,便于后续访问;
  2. 创建一个队列 queue,存储当前需要遍历的节点;
  3. 将起点 0 加入队列中,标记为 visited,存储路径 path;
  4. 当队列不为空的时候,从队首取出一个节点,遍历它的所有邻居节点;
  5. 如果该邻居节点没有被访问过,标记为 visited,存储路径,加入队列中;
  6. 当遍历到终点 n-1 时,存储路径并清空 visited 标记,继续遍历下一个路径。
代码实现
from collections import deque

class Solution:
    def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
        n = len(graph)
        res = []
        visited = [False] * n
        adj = {i: graph[i] for i in range(n)}

        queue = deque()
        queue.append((0, [0]))

        while queue:
            curr, path = queue.popleft()
            visited[curr] = True

            for neighbor in adj[curr]:
                if not visited[neighbor]:
                    if neighbor == n - 1:
                        res.append(path + [neighbor])
                        visited[neighbor] = False
                    else:
                        queue.append((neighbor, path + [neighbor]))

        return res
复杂度分析
  1. 时间复杂度:O(2^n),遍历所有路径最坏情况下需要访问所有节点,数量级为 O(2^n);
  2. 空间复杂度:O(n^2),adj 存储了每个节点可能的所有路径,因此空间占用为 O(n^2)。队列中存储的节点最多不超过 n 个,因此空间占用为 O(n)。总的空间复杂度为 O(n^2 + n),即 O(n^2)。