题目分析
给定一个包含 n 个节点的图,每个节点编号从 1 到 n。对于每个节点 i,存在两条边:i + k 和 i - k,其中 k 是一个给定的整数。我们需要找到从节点 a 到节点 b 的最短路径。
解题思路
由于图的结构特殊,每条边都是节点加减 k,因此我们可以使用双向广度优先搜索(Bidirectional BFS)来找到最短路径。双向 BFS 从起点和终点同时开始搜索,当两者在某个节点相遇时,即找到了最短路径。
代码实现
1. 数据结构:
* 使用两个邻接表 g1 和 g2 分别存储正向和反向的边。
* 使用两个队列 q1 和 q2 分别存储正向和反向的 BFS 队列。
* 使用两个哈希表 vis1 和 vis2 分别记录正向和反向访问过的节点及其步数。
2. BFS 搜索:
* 同时从起点 a 和终点 b 开始搜索。
* 每次从两个队列中分别取出一个节点,进行扩展。
* 如果在扩展过程中,发现某个节点被另一方向的 BFS 访问过,则找到了最短路径。
* 如果搜索完所有可能的路径仍未相遇,则输出 -1 表示无解。
3. 输入输出:
* 输入包括节点数 n,起点 a,终点 b,以及边的变化量 k。
* 输出从起点到终点的最短路径长度。
时间复杂度分析
代码的时间复杂度主要由广度优先搜索(BFS)决定:
1. 图的构建:
* 构建图的时间复杂度为 O(n),因为我们需要遍历每个节点,并为每个节点添加两条边(如果边存在)。
2. 双向 BFS:
* 在最坏的情况下,双向 BFS 需要遍历整个图。由于每次扩展都会访问新的节点,因此时间复杂度取决于节点的访问次数。
* 在双向 BFS 中,每次扩展的节点数最多为 2 * k,因为每个节点最多有两条边(一条是加 k,一条是减 k)。
* 因此,双向 BFS 的时间复杂度为 O(n / k),其中 n 是节点数,k 是边的变化量。
3. 总时间复杂度:
* 总时间复杂度为 O(n + n / k) = O(n)。
综上所述,上述代码的时间复杂度为 O(n)。
代码注释