新增道路查询后的最短距离 I
题目描述
给你一个整数 n
和一个二维整数数组 queries
。
有 n
个城市,编号从 0
到 n - 1
。初始时,每个城市 i
都有一条单向道路通往城市 i + 1
(0 <= i < n - 1
)。
queries[i] = [ui, vi]
表示新建一条从城市 ui
到城市 vi
的单向道路。每次查询后,你需要找到从城市 0
到城市 n - 1
的最短路径的长度。
返回一个数组 answer
,对于范围 [0, queries.length - 1]
中的每个 i
,answer[i]
是处理完前 i + 1
个查询后,从城市 0
到城市 n - 1
的最短路径的长度。
示例 1:
输入:
n = 5, queries = [[2, 4], [0, 2], [0, 4]]
输出:
[3, 2, 1]
解释:
- 新增一条从
2
到4
的道路后,从0
到4
的最短路径长度为3
。 - 新增一条从
0
到2
的道路后,从0
到4
的最短路径长度为2
。 - 新增一条从
0
到4
的道路后,从0
到4
的最短路径长度为1
。
示例 2:
输入:
n = 4, queries = [[0, 3], [0, 2]]
输出:
[1, 1]
scss
复制代码
解释:
- 新增一条从
0
到3
的道路后,从0
到3
的最短路径长度为1
。 - 新增一条从
0
到2
的道路后,从0
到3
的最短路径长度仍为1
。
提示:
3 <= n <= 500
1 <= queries.length <= 500
queries[i].length == 2
0 <= queries[i][0] < queries[i][1] < n
1 < queries[i][1] - queries[i][0]
- 查询中没有重复的道路。
解题思路
这道题可以使用动态更新的最短路径计算来完成。主要思路如下:
- 初始状态下,城市
0
到城市n-1
的路径是逐个城市依次通行的,因此每个城市的距离就是它的编号。 - 每次查询新增一条道路时,只需更新与该条道路相关的节点的最短路径。
- 对于每个查询后的结果,计算从城市
0
到城市n-1
的最短路径,并保存到结果数组中。 - 因为题目说
queries[i][0] < queries[i][1]
,所以只需要从queries[i][1]
开始更新即可
代码实现
以下是使用 C++ 实现的代码:
class Solution {
public:
vector<int> shortestDistanceAfterQueries(int n, vector<vector<int>>& queries) {
vector<vector<int>> pre(n, vector<int>()); // 记录每个节点的前驱节点
vector<int> dis(n, 0), res; // dis 保存每个节点到达的最短距离
// 初始化城市的直接路径
for (int i = 1; i < n; i++) {
dis[i] = i; // 初始路径长度为城市编号差值
pre[i].push_back(i - 1); // 每个城市的前驱是前一个城市
}
// 处理每个查询
for (auto& c : queries) {
int x = c[0], y = c[1];
pre[y].push_back(x); // 添加新路径的前驱
// 更新从 y 到 n-1 的最短路径
for (int i = y; i < n; i++) {
for (auto v : pre[i]) {
dis[i] = min(dis[i], dis[v] + 1); // 更新最短路径
}
}
// 记录当前从 0 到 n-1 的最短路径
res.push_back(dis[n - 1]);
}
return res;
}
};