一、题目
给你一个整数 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
的最短路径的长度。
二、输入
城市数和查询数组
三、输出
返回一个数组 answer,
对于范围 [0, queries.length - 1]
中的每个 i,answer[i] 是处理完前 i + 1
个查询后,从城市 0 到城市 n - 1
的最短路径的长度。
四、示例
输入:
n = 5, queries = [[2, 4], [0, 2], [0, 4]]
输出:
[3, 2, 1]
输入:
n = 4, queries = [[0, 3], [0, 2]]
输出:
[1, 1]
五、题解
5.1 Java 实现
package org.stone.study.algo.ex202411;
import java.util.*;
public class ShortestPaths {
public static void main(String[] args) {
int n = 5;
int[][] queries = {{2, 4}, {0, 2}, {0, 4}};
int[] ans = new ShortestPaths().shortestDistanceAfterQueries2(n, queries);
System.out.println(Arrays.toString(ans));
}
public int[] shortestDistanceAfterQueries(int n, int[][] queries) {
List<Integer>[] neighbors = new ArrayList[n];
for(int i = 0; i < n - 1; i++) {
neighbors[i] = new ArrayList<>();
neighbors[i].add(i + 1);
}
neighbors[n-1] = new ArrayList<>();
int m = queries.length;
int[] ans = new int[m];
for(int i = 0; i < m; i++) {
int[] query = queries[i];
neighbors[query[0]].add(query[1]);
ans[i] = bfs(neighbors);
}
return ans;
}
private int bfs(List<Integer>[] neighbors) {
int n = neighbors.length;
int[] dist = new int[n];
Arrays.fill(dist, -1);
Queue<Integer> queue = new LinkedList<>();
queue.offer(0);
dist[0] = 0;
while(!queue.isEmpty()) {
int cur = queue.poll();
for(int neighbor : neighbors[cur]) {
if (dist[neighbor] < 0) {
queue.offer(neighbor);
dist[neighbor] = dist[cur] + 1;
}
}
}
return dist[n - 1];
}
public int[] shortestDistanceAfterQueries2(int n, int[][] queries) {
int[] ans = new int[queries.length];
int[] dp = new int[n];
ArrayList<Integer>[] preNodes = new ArrayList[n];
for (int i = 1; i < n; i++) {
dp[i] = i;
preNodes[i] = new ArrayList<Integer>();
preNodes[i].add(i-1);
}
for (int i = 0; i < queries.length; i++) {
int u = queries[i][0], v = queries[i][1];
preNodes[v].add(u);
for(int j = v; j < n; j++) {
for(int pre : preNodes[j]) {
if (dp[pre] + 1 < dp[j]) {
dp[j] = dp[pre] + 1;
}
}
}
ans[i] = dp[n-1];
}
return ans;
}
}
5.2 Python实现
def shortPath(n, queries):
pre = [[i - 1] for i in range(n)]
pre[0] = []
dp = [i for i in range(n)]
ans = []
for (u, v) in queries:
pre[v].append(u)
for j in range(v, n):
for k in pre[j]:
dp[j] = min(dp[j], dp[k] + 1)
ans.append(dp[n - 1])
return ans
if __name__ == '__main__':
n = 5
queries = [[2, 4], [0, 2], [0, 4]]
ans = shortPath(n, queries)
print(ans)