classSolution { publicintnumBusesToDestination(int[][] routes, int source, int target) { if (source == target) { return0; } // Store for a given stop, which route(s) contain such stop // This means from this stop, all the stops in the routes that contain such stop // can be arrived by taking one bus Map<Integer, List<Integer>> stopRoutesMap = newHashMap<>(); for (inti=0; i < routes.length; i++) { for (int stop : routes[i]) { stopRoutesMap.putIfAbsent(stop, newArrayList<>()); stopRoutesMap.get(stop).add(i); } } Queue<Integer> stopQueue = newLinkedList<>(); Set<Integer> visited = newHashSet<>(); boolean[] visitedRoutes = newboolean[routes.length]; intbusNum=0; stopQueue.offer(source); visited.add(source); while (!stopQueue.isEmpty()) { // Currently the queue contains all the stops that we can arrive with busNum // buses intsize= stopQueue.size(); for (inti=0; i < size; i++) { intcurrStop= stopQueue.poll(); List<Integer> routesInvolved = stopRoutesMap.get(currStop); for (Integer routeNum : routesInvolved) { if (visitedRoutes[routeNum]) { continue; } int[] stopOfCurrRoute = routes[routeNum]; for (int stop : stopOfCurrRoute) { if (visited.add(stop)) { if (stop == target) { return busNum + 1; } else { stopQueue.offer(stop); } } } visitedRoutes[routeNum] = true; } } // Right now, the queue contains all the stops that need busNum + 1 buses to // arrive // so we update busNum now busNum += 1; } return -1; } }