朴素BFS,擦边过。。不难,但是绕,需要想清楚。
大致描述一下做法吧,首先枚举能经过起点站的公交车,将公交车入队列。
然后对当前公交车能到达的每一站,看能否换乘其它公交车,将其它公交车入队。
注意,已经“坐过”的公交车就没有意义再坐一次了,当然,已经去过的站也没有必要再去一次了。所以有两个visitedSet
class Solution {
public int numBusesToDestination(int[][] routes, int source, int target) {
if (source == target) return 0;
Map<Integer, List<Integer>> station = new HashMap<>();
int n = routes.length;
for (int i=0;i<n;i++) {
for (int j=0;j<routes[i].length;j++){
if (!station.containsKey(routes[i][j])) {
station.put(routes[i][j], new ArrayList<>());
}
station.get(routes[i][j]).add(i);
}
}
if (!station.containsKey(target)) return -1;
Set<Integer> set = new HashSet<>();
set.add(source);
Queue<Integer> q = new ArrayDeque<>();
Queue<Set<Integer>> visitedQ = new ArrayDeque<>();
Queue<Set<Integer>> visitedBus = new ArrayDeque<>();
Queue<Integer> cntQ = new ArrayDeque<>();
q.add(source);
visitedQ.add(set);
cntQ.add(1);
Set<Integer> setBus = new HashSet<>();
visitedBus.add(setBus);
while (!q.isEmpty()) {
Integer curStation = q.poll();
Set<Integer> visited = visitedQ.poll();
int cnt = cntQ.poll();
Set<Integer> vBus = visitedBus.poll();
List<Integer> bus = station.get(curStation);
if (bus!=null) {
for (Integer curBus : bus) {
if (vBus.contains(curBus)) continue;
int[] route = routes[curBus];
for (int nextStation : route) {
if (!visited.contains(nextStation)) {
if (nextStation == target) {
return cnt;
} else {
q.add(nextStation);
Set<Integer> newVis = new HashSet<>(visited);
newVis.add(nextStation);
visitedQ.add(newVis);
cntQ.add(cnt + 1);
Set<Integer> newVBus = new HashSet<>(vBus);
newVBus.add(curBus);
visitedBus.add(newVBus);
}
}
}
}
}
}
return -1;
}
}