LeetCode 题解工作台

到达目的地的方案数

你在一个城市里,城市由 n 个路口组成,路口编号为 0 到 n - 1 ,某些路口之间有 双向 道路。输入保证你可以从任意路口出发到达其他任意路口,且任意两个路口之间最多有一条路。 给你一个整数 n 和二维整数数组 roads ,其中 roads[i] = [u i , v i , time i ]…

category

4

题型

code_blocks

5

代码语言

hub

3

相关题

当前训练重点

中等 · 动态·规划

bolt

答案摘要

我们定义以下几个数组,其中: - `g` 表示图的邻接矩阵,`g[i][j]` 表示点 `i` 到点 `j` 的最短路径长度,初始时全部为 ,而 `g[0][0]` 为 ;然后我们遍历 `roads`,将 `g[u][v]` 和 `g[v][u]` 更新为 `t`;

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 动态·规划 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

你在一个城市里,城市由 n 个路口组成,路口编号为 0 到 n - 1 ,某些路口之间有 双向 道路。输入保证你可以从任意路口出发到达其他任意路口,且任意两个路口之间最多有一条路。

给你一个整数 n 和二维整数数组 roads ,其中 roads[i] = [ui, vi, timei] 表示在路口 ui 和 vi 之间有一条需要花费 timei 时间才能通过的道路。你想知道花费 最少时间 从路口 0 出发到达路口 n - 1 的方案数。

请返回花费 最少时间 到达目的地的 路径数目 。由于答案可能很大,将结果对 109 + 7 取余 后返回。

 

示例 1:

输入:n = 7, roads = [[0,6,7],[0,1,2],[1,2,3],[1,3,3],[6,3,3],[3,5,1],[6,5,1],[2,5,1],[0,4,5],[4,6,2]]
输出:4
解释:从路口 0 出发到路口 6 花费的最少时间是 7 分钟。
四条花费 7 分钟的路径分别为:
- 0 ➝ 6
- 0 ➝ 4 ➝ 6
- 0 ➝ 1 ➝ 2 ➝ 5 ➝ 6
- 0 ➝ 1 ➝ 3 ➝ 5 ➝ 6

示例 2:

输入:n = 2, roads = [[1,0,10]]
输出:1
解释:只有一条从路口 0 到路口 1 的路,花费 10 分钟。

 

提示:

  • 1 <= n <= 200
  • n - 1 <= roads.length <= n * (n - 1) / 2
  • roads[i].length == 3
  • 0 <= ui, vi <= n - 1
  • 1 <= timei <= 109
  • ui != vi
  • 任意两个路口之间至多有一条路。
  • 从任意路口出发,你能够到达其他任意路口。
lightbulb

解题思路

方法一:朴素 Dijkstra 算法

我们定义以下几个数组,其中:

  • g 表示图的邻接矩阵,g[i][j] 表示点 i 到点 j 的最短路径长度,初始时全部为 \infty,而 g[0][0]00;然后我们遍历 roads,将 g[u][v]g[v][u] 更新为 t
  • dist[i] 表示从起点到点 i 的最短路径长度,初始时全部为 \infty,而 dist[0]00
  • f[i] 表示从起点到点 i 的最短路径的条数,初始时全部为 00,而 f[0]11
  • vis[i] 表示点 i 是否已经被访问过,初始时全部为 False

然后,我们使用朴素 Dijkstra 算法求出从起点到终点的最短路径长度,过程中同时记录下每个点的最短路径的条数。

最后,我们返回 f[n - 1] 即可。由于答案可能很大,我们需要对 109+710^9 + 7 取模。

时间复杂度 O(n2)O(n^2),空间复杂度 O(n2)O(n^2)。其中 nn 为点的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution:
    def countPaths(self, n: int, roads: List[List[int]]) -> int:
        g = [[inf] * n for _ in range(n)]
        for u, v, t in roads:
            g[u][v] = g[v][u] = t
        g[0][0] = 0
        dist = [inf] * n
        dist[0] = 0
        f = [0] * n
        f[0] = 1
        vis = [False] * n
        for _ in range(n):
            t = -1
            for j in range(n):
                if not vis[j] and (t == -1 or dist[j] < dist[t]):
                    t = j
            vis[t] = True
            for j in range(n):
                if j == t:
                    continue
                ne = dist[t] + g[t][j]
                if dist[j] > ne:
                    dist[j] = ne
                    f[j] = f[t]
                elif dist[j] == ne:
                    f[j] += f[t]
        mod = 10**9 + 7
        return f[-1] % mod
speed

复杂度分析

指标
时间O(N^3)
空间O(N^2)
psychology

面试官常问的追问

外企场景
  • question_mark

    The candidate effectively uses dynamic programming to calculate the number of shortest paths.

  • question_mark

    The candidate demonstrates understanding of graph algorithms and topological sorting.

  • question_mark

    The candidate correctly handles modular arithmetic and edge cases involving multiple shortest paths.

warning

常见陷阱

外企场景
  • error

    Failing to handle multiple shortest paths correctly.

  • error

    Incorrect use of the topological order when updating the dynamic programming table.

  • error

    Not applying modular arithmetic as specified in the problem statement.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Consider a version where roads have different weights or are directed.

  • arrow_right_alt

    Implement an optimized version using BFS for unweighted graphs.

  • arrow_right_alt

    Extend the problem to calculate the number of paths in graphs with cycles.

help

常见问题

外企场景

到达目的地的方案数题解:动态·规划 | LeetCode #1976 中等