BFS. Use two sets to store visited routes and stops.
class Solution {
public int numBusesToDestination(int[][] routes, int source, int target) {
Map<Integer, List<Integer>> stopToRouteMap = new HashMap<>();
for (int i = 0; i < routes.length; i++) {
for (int j = 0; j < routes[i].length; j++) {
if (!stopToRouteMap.containsKey(routes[i][j])) {
stopToRouteMap.put(routes[i][j], new ArrayList<>());
}
stopToRouteMap.get(routes[i][j]).add(i);
}
}
if (!stopToRouteMap.containsKey(source)) {
return -1;
}
// [[1,2,7],[3,6,7]]
// 1: 0
// 2: 0
// 3: 1
// 6: 2
// 7: 1,2
Queue<Integer> queue = new LinkedList<>();
queue.offer(source);
Set<Integer> stopVisited = new HashSet<>();
Set<Integer> routeVisited = new HashSet<>();
stopVisited.add(source);
int numOfBuses = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int curStop = queue.poll();
if (curStop == target) {
return numOfBuses;
}
if (stopToRouteMap.containsKey(curStop)) {
List<Integer> curRoutes = stopToRouteMap.get(curStop);
for (int route : curRoutes) {
if (routeVisited.contains(route)) {
continue;
}
routeVisited.add(route);
int[] stops = routes[route];
for (int stop : stops) {
if (!stopVisited.contains(stop)) {
queue.offer(stop);
stopVisited.add(stop);
}
}
}
}
}
numOfBuses ++;
}
return -1;
}
}