追逐游戏
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 263 ms, 内存: 55.1 MB
/*
题目思路:
1. 建立图的表示:使用邻接表来表示无向图。
2. BFS策略:使用广度优先搜索来计算小力从起点到达其他点的最短距离,同时计算小扣从起点到达其他点的最短距离。
3. 最优策略:小力追小扣的过程中,小力每次尽量靠近小扣,而小扣则尽量远离小力。
4. 终止条件:一旦小力与小扣在同一位置则游戏结束,否则若小力无法追上小扣则返回 -1。
*/
import java.util.*;
import java.util.stream.Collectors;
public class ChasingGameStream {
public int minRoundsToCatch(int[][] edges, int startA, int startB) {
int n = edges.length;
Map<Integer, List<Integer>> graph = Arrays.stream(edges).collect(Collectors.groupingBy(
edge -> edge[0], Collectors.mapping(edge -> edge[1], Collectors.toList())
));
graph.putAll(Arrays.stream(edges).collect(Collectors.groupingBy(
edge -> edge[1], Collectors.mapping(edge -> edge[0], Collectors.toList())
)));
int[] distA = bfs(graph, startA, n);
int[] distB = bfs(graph, startB, n);
return IntStream.range(1, n + 1).filter(i -> distA[i] <= distB[i]).findFirst().orElse(-1);
}
private int[] bfs(Map<Integer, List<Integer>> graph, int start, int n) {
int[] dist = new int[n + 1];
Arrays.fill(dist, -1);
Queue<Integer> queue = new LinkedList<>();
queue.offer(start);
dist[start] = 0;
while (!queue.isEmpty()) {
int node = queue.poll();
graph.getOrDefault(node, Collections.emptyList()).stream()
.filter(neighbor -> dist[neighbor] == -1)
.forEach(neighbor -> {
dist[neighbor] = dist[node] + 1;
queue.offer(neighbor);
});
}
return dist;
}
}
解释
方法:
该题解首先处理输入的边列表构建了一个无向图,并计算了每个节点的度。接着使用宽度优先搜索(BFS)来计算从起始点sta和stb到每个节点的最短距离。通过比较这两个距离数组,确定是否存在一个位置i使得小扣在小力之前到达且小力无法在下一步直接到达。如果存在这样的点,并且该点不是一个环路中的节点(即度大于1),则返回-1表示小力无法追上小扣。否则,计算小力追上小扣所需的最大距离,即为答案。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中您提到构建无向图,但没有明确说明如何处理重复边或自环(如果存在的话),请问这种情况在题目中有可能发生吗?
▷🦆
题解中使用了宽度优先搜索(BFS)来找到从两个起始点到所有其他节点的最短距离。为什么选择BFS而不是DFS或其他路径查找算法?
▷🦆
您在代码中减少了每个节点的度并检查度为1的情况。在游戏逻辑中,节点的度数为1(即叶子节点)具有什么特殊意义?
▷