leetcode
leetcode 451 ~ 500
从始点到终点的所有路径

从始点到终点的所有路径

难度:

标签:

题目描述

代码结果

运行时间: 45 ms, 内存: 19.2 MB


/*
 * LeetCode题目: 从始点到终点的所有路径
 * 题目思路: 
 * 使用Java Stream API来实现DFS。
 * Stream API不太适合直接进行递归,因此我们还是需要在DFS方法中使用递归。
 * 通过Stream API,我们可以更简洁地操作集合。
 */
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
public class AllPathsFromSourceToTargetStream {
    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
        List<List<Integer>> results = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        path.add(0);
        dfs(graph, 0, path, results);
        return results;
    }
 
    private void dfs(int[][] graph, int node, List<Integer> path, List<List<Integer>> results) {
        if (node == graph.length - 1) {
            results.add(new ArrayList<>(path));
            return;
        }
        List<Integer> nextNodes = IntStream.of(graph[node]).boxed().collect(Collectors.toList());
        nextNodes.forEach(nextNode -> {
            path.add(nextNode);
            dfs(graph, nextNode, path, results);
            path.remove(path.size() - 1);
        });
    }
}
 

解释

方法:

该题解采用了逆向拓扑排序的方法来解决问题。首先,根据输入的边构建了一个逆向的邻接表,即对于每个边(u, v),在邻接表中v指向u。同时,使用一个计数器数组来记录每个节点入边的数量。如果终点destination的入边不为0,直接返回False,因为终点不应该有出边。之后使用一个队列来进行逆向拓扑排序,从终点开始,每次从队列中取出一个节点,检查该节点是否为始点source,是则返回True。对于该节点的每个邻居,减少它的入边计数,并在入边计数为0时将其加入队列。如果队列处理完,始点未被访问到,则返回False。这个方法主要是检查是否存在从source到destination的有效路径。

时间复杂度:

O(V + E)

空间复杂度:

O(V)

代码细节讲解

🦆
在构建逆向邻接表时,为何选择将每个边(u, v)存储为v指向u而不是u指向v?
在构建逆向邻接表的时候,选择将每个边(u, v)存储为v指向u是为了实现逆向拓扑排序。逆向拓扑排序是从终点开始,逐步退回到起点的过程。通过将边逆向存储,我们可以从终点开始,沿着逆向的边移动,逐步退回到起点。这种方法可以在不追踪已访问节点的情况下,验证是否存在一条从起点到终点的有效路径。
🦆
逆向拓扑排序在此题中的作用是什么?它是如何确保可以找到从起点到终点的有效路径的?
逆向拓扑排序在此题中的作用是从终点开始,逐步检查每个可到达的节点,直到到达起点或者无更多节点可访问。通过这种方式,我们可以有效地确认是否存在一条从起点到终点的路径。在逆向拓扑排序过程中,我们使用一个入边计数器来管理每个节点的入边数量。只有当一个节点的所有入边都被访问过(即入边计数为0时),这个节点才会被加入到处理队列中。这确保了我们按照正确的顺序访问节点,从而可以正确地验证从起点到终点的路径是否存在。
🦆
为什么在检查终点destination时,如果其入边不为0则直接返回False?终点在逻辑上应具备什么样的特性?
在检查终点destination时,如果其入边不为0则直接返回False,因为在一个有效的有向无环图中,终点不应有任何出边(即没有其他节点指向终点之外的节点)。如果终点的入边计数不为0,说明存在指向终点的边,这违背了终点应是图中最后一个节点的特性。因此,如果终点的入边计数不为0,我们可以断定不存在一条有效的从起点到终点的路径,因此返回False。

相关问题