到达目的地的第二短时间
难度:困难
最近困难题也太多了吧 ̄へ ̄
刚开始尝试用dfs解题,但后面发现是无向图,所以只能放弃/(ㄒoㄒ)/~~
后面也没能做出来,还是看看题解吧
广度优先算法(BFS):
1、把根节点放到队列的末尾。
2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。
回归本题,本题要求的是次最短,那么就可以使用一个二维的数组或者两个一维的,记录到每个节点的最短路径。
可以使用dist1保存最短,dist2保存次最短~
代码如下:
public int secondMinimum(int n, int[][] edges, int time, int change) {
// 处理无向图路径
List<Integer>[] grap = new List[n + 1];
for (int i = 0; i <= n; i++) {
grap[i] = new ArrayList<Integer>();
}
for (int[] edge : edges) {
grap[edge[0]].add(edge[1]);
grap[edge[1]].add(edge[0]);
}
// dist1[i] 记录到节点i的最短路径 dist2[i]记录到节点i的次最短路径
int [] dist1 = new int[n+1];
int [] dist2 = new int[n+1];
Arrays.fill(dist1, Integer.MAX_VALUE);
Arrays.fill(dist2, Integer.MAX_VALUE);
// 队列
Queue<int[]> queue = new ArrayDeque<int[]>();
// 第一个节点入队 <index,step>
queue.offer(new int[]{1, 0});
// 同样的配方不一样的面~
while (dist2[n] == Integer.MAX_VALUE) {
int[] arr = queue.poll();
int cur = arr[0], len = arr[1];
for (int next : grap[cur]) {
// 更新最短和次最短的步数
if (len + 1 < dist1[next]) {
dist1[next] = len + 1;
queue.offer(new int[]{next, len + 1});
}// 次最短路径步数 并加入队列中
else if (len + 1 > dist1[next] && len + 1 < dist2[next]) {
dist2[next] = len + 1;
queue.offer(new int[]{next, len + 1});
}
}
}
// 计算次最短路径的时间
int result = 0;
for (int i = 0; i < dist2[n]; i++) {
// 需要加入等红绿灯的时间 由于红绿转换 所以循环是时间 2*change
if (result % (2 * change) >= change) { //遇到红灯
// 比如time等于3 change=5 这个时候result如果等于6 就需要等4分钟 (2*5)-6%10 = 10-6 = 4
result = result + (2 * change - result % (2 * change));
}
// 加上路径的时间
result = result + time;
}
return result;
}
执行结果:成功