-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy path0815-bus-routes.js
62 lines (55 loc) · 1.8 KB
/
0815-bus-routes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
* 815. Bus Routes
* https://leetcode.com/problems/bus-routes/
* Difficulty: Hard
*
* 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 the 0th bus travels in the sequence
* 1 -> 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.
*/
/**
* @param {number[][]} routes
* @param {number} source
* @param {number} target
* @return {number}
*/
var numBusesToDestination = function(routes, source, target) {
if (source === target) return 0;
const stopToBuses = new Map();
for (let busId = 0; busId < routes.length; busId++) {
for (const stop of routes[busId]) {
if (!stopToBuses.has(stop)) {
stopToBuses.set(stop, []);
}
stopToBuses.get(stop).push(busId);
}
}
if (!stopToBuses.has(source) || !stopToBuses.has(target)) return -1;
const visitedBuses = new Set();
const visitedStops = new Set([source]);
const queue = [[source, 0]];
while (queue.length > 0) {
const [currentStop, busCount] = queue.shift();
if (currentStop === target) return busCount;
for (const busId of stopToBuses.get(currentStop)) {
if (visitedBuses.has(busId)) continue;
visitedBuses.add(busId);
for (const nextStop of routes[busId]) {
if (visitedStops.has(nextStop)) continue;
visitedStops.add(nextStop);
queue.push([nextStop, busCount + 1]);
if (nextStop === target) return busCount + 1;
}
}
}
return -1;
};