版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Viscu/article/details/82531150
我们有一系列公交路线。每一条路线 routes[i] 上都有一辆公交车在上面循环行驶。例如,有一条路线 routes[0] = [1, 5, 7],表示第一辆 (下标为0) 公交车会一直按照 1->5->7->1->5->7->1->… 的车站路线行驶。
假设我们从 S 车站开始(初始时不在公交车上),要去往 T 站。 期间仅可乘坐公交车,求出最少乘坐的公交车数量。返回 -1 表示不可能到达终点车站。
示例:
输入:
routes = [[1, 2, 7], [3, 6, 7]]
S = 1
T = 6
输出: 2
解释:
最优策略是先乘坐第一辆公交车到达车站 7, 然后换乘第二辆公交车到车站 6。
说明:
1 <= routes.length <= 500.
1 <= routes[i].length <= 500.
0 <= routes[i][j] < 10 ^ 6.
思路:这道题目就是个图的知识,
所以我们的出发点就是应该从图的角度来解。
首先呢,一个节点可能对应有多条节点(多条边)(一个公交车节点连接着多个公交车站节点,一个公交车站节点可能连接多个公交车节点) 所以我们需要遍历一遍,用Map存下
公交站节点所对应的多个公交车节点。 eg: 样例一 对应节点0和1.
我们从S开始,把所有符合公交车站节点S的对应的公交车节(这里是0)点加入队列中.
接着进行bfs搜索,每次搜索,我们将该队列中所有的公交车节点遍历一遍(类似层次遍历),
若遇到公交车站节点T,直接返回ans,若没遇到,每次访问一个公交车站结点,就访问
该公交车站节点所连接的公交车节点,若该公交车节点没有访问过,就加入备用队列(存新添加的未访问的公交车节点)中。
public class __815 {
public int numBusesToDestination(int[][] routes, int S, int T) {
if(S==T){
return 0;
}
Map<Integer,Set<Integer>> map=new HashMap<Integer, Set<Integer>>();
for(int i=0;i<routes.length;++i){
for(int j:routes[i]){
if(!map.containsKey(j)){
map.put(j,new HashSet<Integer>());
}
map.get(j).add(i);
}
}
Queue<Integer> queue=new LinkedList<Integer>();
Set<Integer> vis=new HashSet<Integer>();
for(int st:map.get(S)){
queue.offer(st);
vis.add(st);
}
int ans=1;
while (!queue.isEmpty()){
Queue<Integer> t=new LinkedList<Integer>(); //备用节点存新添加的未访问过的节点
while (!queue.isEmpty()){
int curCar=queue.poll();
for(int k:routes[curCar]){ //遍历当前公交车节点所连接的所有公交车站节点
if(k==T){ //遇到则直接返回结果
return ans;
}
for(int nextCar:map.get(k)){ //遍历当前公交车站节点连接的所有公交车节点
if(!vis.contains(nextCar)){ //未访问过的加入备用队列中
t.offer(nextCar);
vis.add(nextCar);
}
}
}
}
++ans;
queue=t;
}
return -1;
}
public static void main(String[] args) {
int[][] r={{1, 2, 7}, {3, 6, 7}};
System.out.println(new __815().numBusesToDestination(r,1,6));
}
}