Welcome to Subscribe On Youtube
815. Bus Routes
Description
You are given an array routes
representing bus routes where routes[i]
is a bus route that the ith
bus repeats forever.
- For example, if
routes[0] = [1, 5, 7]
, this means that the0th
bus travels in the sequence1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ...
forever.
You will start at the bus stop source
(You are not on any bus initially), and you want to go to the bus stop target
. You can travel between bus stops by buses only.
Return the least number of buses you must take to travel from source
to target
. Return -1
if it is not possible.
Example 1:
Input: routes = [[1,2,7],[3,6,7]], source = 1, target = 6 Output: 2 Explanation: The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.
Example 2:
Input: routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12 Output: -1
Constraints:
1 <= routes.length <= 500
.1 <= routes[i].length <= 105
- All the values of
routes[i]
are unique. sum(routes[i].length) <= 105
0 <= routes[i][j] < 106
0 <= source, target < 106
Solutions
-
class Solution { public int numBusesToDestination(int[][] routes, int source, int target) { if (source == target) { return 0; } int n = routes.length; Set<Integer>[] s = new Set[n]; List<Integer>[] g = new List[n]; Arrays.setAll(s, k -> new HashSet<>()); Arrays.setAll(g, k -> new ArrayList<>()); Map<Integer, List<Integer>> d = new HashMap<>(); for (int i = 0; i < n; ++i) { for (int v : routes[i]) { s[i].add(v); d.computeIfAbsent(v, k -> new ArrayList<>()).add(i); } } for (var ids : d.values()) { int m = ids.size(); for (int i = 0; i < m; ++i) { for (int j = i + 1; j < m; ++j) { int a = ids.get(i), b = ids.get(j); g[a].add(b); g[b].add(a); } } } Deque<Integer> q = new ArrayDeque<>(); Set<Integer> vis = new HashSet<>(); int ans = 1; for (int v : d.get(source)) { q.offer(v); vis.add(v); } while (!q.isEmpty()) { for (int k = q.size(); k > 0; --k) { int i = q.pollFirst(); if (s[i].contains(target)) { return ans; } for (int j : g[i]) { if (!vis.contains(j)) { vis.add(j); q.offer(j); } } } ++ans; } return -1; } }
-
class Solution { public: int numBusesToDestination(vector<vector<int>>& routes, int source, int target) { if (source == target) { return 0; } int n = routes.size(); vector<unordered_set<int>> s(n); vector<vector<int>> g(n); unordered_map<int, vector<int>> d; for (int i = 0; i < n; ++i) { for (int v : routes[i]) { s[i].insert(v); d[v].push_back(i); } } for (auto& [_, ids] : d) { int m = ids.size(); for (int i = 0; i < m; ++i) { for (int j = i + 1; j < m; ++j) { int a = ids[i], b = ids[j]; g[a].push_back(b); g[b].push_back(a); } } } queue<int> q; unordered_set<int> vis; int ans = 1; for (int v : d[source]) { q.push(v); vis.insert(v); } while (!q.empty()) { for (int k = q.size(); k; --k) { int i = q.front(); q.pop(); if (s[i].count(target)) { return ans; } for (int j : g[i]) { if (!vis.count(j)) { vis.insert(j); q.push(j); } } } ++ans; } return -1; } };
-
class Solution: def numBusesToDestination( self, routes: List[List[int]], source: int, target: int ) -> int: if source == target: return 0 s = [set(r) for r in routes] d = defaultdict(list) for i, r in enumerate(routes): for v in r: d[v].append(i) g = defaultdict(list) for ids in d.values(): m = len(ids) for i in range(m): for j in range(i + 1, m): a, b = ids[i], ids[j] g[a].append(b) g[b].append(a) q = deque(d[source]) ans = 1 vis = set(d[source]) while q: for _ in range(len(q)): i = q.popleft() if target in s[i]: return ans for j in g[i]: if j not in vis: vis.add(j) q.append(j) ans += 1 return -1
-
func numBusesToDestination(routes [][]int, source int, target int) int { if source == target { return 0 } n := len(routes) s := make([]map[int]bool, n) g := make([][]int, n) d := map[int][]int{} for i, r := range routes { for _, v := range r { if s[i] == nil { s[i] = make(map[int]bool) } s[i][v] = true d[v] = append(d[v], i) } } for _, ids := range d { m := len(ids) for i := 0; i < m; i++ { for j := i + 1; j < m; j++ { a, b := ids[i], ids[j] g[a] = append(g[a], b) g[b] = append(g[b], a) } } } q := d[source] vis := map[int]bool{} for _, v := range d[source] { vis[v] = true } ans := 1 for len(q) > 0 { for k := len(q); k > 0; k-- { i := q[0] q = q[1:] if s[i][target] { return ans } for _, j := range g[i] { if !vis[j] { vis[j] = true q = append(q, j) } } } ans++ } return -1 }
-
public class Solution { public int NumBusesToDestination(int[][] routes, int source, int target) { if (source == target) { return 0; } Dictionary<int, HashSet<int>> stopToRoutes = new Dictionary<int, HashSet<int>>(); List<HashSet<int>> routeToStops = new List<HashSet<int>>(); for (int i = 0; i < routes.Length; i++) { routeToStops.Add(new HashSet<int>()); foreach (int stop in routes[i]) { routeToStops[i].Add(stop); if (!stopToRoutes.ContainsKey(stop)) { stopToRoutes[stop] = new HashSet<int>(); } stopToRoutes[stop].Add(i); } } Queue<int> queue = new Queue<int>(); HashSet<int> visited = new HashSet<int>(); int ans = 0; foreach (int routeId in stopToRoutes[source]) { queue.Enqueue(routeId); visited.Add(routeId); } while (queue.Count > 0) { int count = queue.Count; ans++; for (int i = 0; i < count; i++) { int routeId = queue.Dequeue(); foreach (int stop in routeToStops[routeId]) { if (stop == target) { return ans; } foreach (int nextRoute in stopToRoutes[stop]) { if (!visited.Contains(nextRoute)) { visited.Add(nextRoute); queue.Enqueue(nextRoute); } } } } } return -1; } }
-
function numBusesToDestination(routes: number[][], source: number, target: number): number { if (source === target) { return 0; } const g: Map<number, number[]> = new Map(); for (let i = 0; i < routes.length; i++) { for (const stop of routes[i]) { if (!g.has(stop)) { g.set(stop, []); } g.get(stop)!.push(i); } } if (!g.has(source) || !g.has(target)) { return -1; } const q: [number, number][] = [[source, 0]]; const visBus: Set<number> = new Set(); const visStop: Set<number> = new Set([source]); for (const [stop, busCount] of q) { if (stop === target) { return busCount; } for (const bus of g.get(stop)!) { if (!visBus.has(bus)) { visBus.add(bus); for (const nextStop of routes[bus]) { if (!visStop.has(nextStop)) { visStop.add(nextStop); q.push([nextStop, busCount + 1]); } } } } } return -1; }