Skip to content

Commit

Permalink
add 815. Bus Routes
Browse files Browse the repository at this point in the history
  • Loading branch information
sayeed205 committed Nov 12, 2023
1 parent b0a636f commit dd37244
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .idea/JetClient/state.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/LeetCode-Practice.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions Hard/815. Bus Routes/815. Bus Routes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import java.util.*;

public class Solution {
public int numBusesToDestination(int[][] routes, int source, int target) {
if (source == target) {
return 0;
}

Map<Integer, List<Integer>> stopToRoutes = new HashMap<>();
Set<Integer> visitedRoutes = new HashSet<>();

for (int i = 0; i < routes.length; i++) {
for (int stop : routes[i]) {
stopToRoutes.computeIfAbsent(stop, k -> new ArrayList<>()).add(i);
}
}

Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{source, 0});

while (!queue.isEmpty()) {
int[] currentStopAndSteps = queue.poll();
int currentStop = currentStopAndSteps[0];
int steps = currentStopAndSteps[1];

for (int routeIndex : stopToRoutes.getOrDefault(currentStop, Collections.emptyList())) {
if (visitedRoutes.contains(routeIndex)) {
continue;
}

visitedRoutes.add(routeIndex);

for (int nextStop : routes[routeIndex]) {
if (nextStop == target) {
return steps + 1;
}

queue.offer(new int[]{nextStop, steps + 1});
}
}
}

return -1;
}
}
47 changes: 47 additions & 0 deletions Hard/815. Bus Routes/815. Bus Routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @param {number[][]} routes
* @param {number} source
* @param {number} target
* @return {number}
*/
var numBusesToDestination = function (routes, source, target) {
if (source === target) {
return 0;
}

const stopToRoutes = new Map();

for (let i = 0; i < routes.length; i++) {
for (const stop of routes[i]) {
if (!stopToRoutes.has(stop)) {
stopToRoutes.set(stop, []);
}
stopToRoutes.get(stop).push(i);
}
}

const visitedRoutes = new Set();
const queue = [[source, 0]];

while (queue.length > 0) {
const [currentStop, steps] = queue.shift();

for (const routeIndex of stopToRoutes.get(currentStop) || []) {
if (visitedRoutes.has(routeIndex)) {
continue;
}

visitedRoutes.add(routeIndex);

for (const nextStop of routes[routeIndex]) {
if (nextStop === target) {
return steps + 1;
}

queue.push([nextStop, steps + 1]);
}
}
}

return -1;
};
33 changes: 33 additions & 0 deletions Hard/815. Bus Routes/815. Bus Routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from collections import defaultdict, deque
from typing import List

class Solution:
def numBusesToDestination(self, routes: List[List[int]], source: int, target: int) -> int:
if source == target:
return 0

stop_to_routes = defaultdict(list)

for i, route in enumerate(routes):
for stop in route:
stop_to_routes[stop].append(i)

visited_routes = set()
queue = deque([(source, 0)])

while queue:
current_stop, steps = queue.popleft()

for route_index in stop_to_routes[current_stop]:
if route_index in visited_routes:
continue

visited_routes.add(route_index)

for next_stop in routes[route_index]:
if next_stop == target:
return steps + 1

queue.append((next_stop, steps + 1))

return -1
43 changes: 43 additions & 0 deletions Hard/815. Bus Routes/815. Bus Routes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use std::collections::{HashMap, HashSet, VecDeque};

impl Solution {
pub fn num_buses_to_destination(routes: Vec<Vec<i32>>, source: i32, target: i32) -> i32 {
if source == target {
return 0;
}

let mut stop_to_routes: HashMap<i32, Vec<usize>> = HashMap::new();
for (i, route) in routes.iter().enumerate() {
for stop in route {
stop_to_routes
.entry(*stop)
.or_insert_with(Vec::new)
.push(i);
}
}

let mut visited_routes = HashSet::new();
let mut queue = VecDeque::new();
queue.push_back((source, 0));

while !queue.is_empty() {
let (current_stop, steps) = queue.pop_front().unwrap();

for &route_index in stop_to_routes.get(&current_stop).unwrap_or(&Vec::new()) {
if visited_routes.contains(&route_index) {
continue;
}
visited_routes.insert(route_index);

for &next_stop in routes[route_index].iter() {
if next_stop == target {
return steps + 1;
}
queue.push_back((next_stop, steps + 1));
}
}
}

-1
}
}
45 changes: 45 additions & 0 deletions Hard/815. Bus Routes/815. Bus Routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
function numBusesToDestination(
routes: number[][],
source: number,
target: number
): number {
if (source === target) {
return 0;
}

const stopToRoutes: Map<number, number[]> = new Map();

for (let i = 0; i < routes.length; i++) {
for (const stop of routes[i]) {
if (!stopToRoutes.has(stop)) {
stopToRoutes.set(stop, []);
}
stopToRoutes.get(stop)!.push(i);
}
}

const visitedRoutes: Set<number> = new Set();
const queue: [number, number][] = [[source, 0]];

while (queue.length > 0) {
const [currentStop, steps] = queue.shift()!;

for (const routeIndex of stopToRoutes.get(currentStop) || []) {
if (visitedRoutes.has(routeIndex)) {
continue;
}

visitedRoutes.add(routeIndex);

for (const nextStop of routes[routeIndex]) {
if (nextStop === target) {
return steps + 1;
}

queue.push([nextStop, steps + 1]);
}
}
}

return -1;
}
33 changes: 33 additions & 0 deletions Hard/815. Bus Routes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## [815. Bus Routes](https://leetcode.com/problems/bus-routes/)

You are given an array `routes` representing bus routes where `routes[i]` is a bus route that the <code>i<sup>th</sup></code> bus repeats forever.

- For example, if `routes[0] = [1, 5, 7]`, this means that the <code>0<sup>th</sup></code> bus travels in the sequence <code>1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1 -> ...</code> 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:

<pre>
<strong>Input:</strong> routes = [[1,2,7],[3,6,7]], source = 1, target = 6
<strong>Output:</strong> 2
<strong>Explanation:</strong> The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.
</pre>

#### Example 2:

<pre>
<strong>Input:</strong> routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12
<strong>Output:</strong> -1
</pre>

#### Constraints:

- `1 <= routes.length <= 500`.
- <code>1 <= routes[i].length <= 10<sup>5</sup></code>
- All the values of `routes[i]` are **unique**.
- <code>sum(routes[i].length) <= 10<sup>5</sup></code>
- <code>0 <= routes[i][j] < 10<sup>6</sup></code>
- <code>0 <= source, target < 10<sup>6</sup></code>

0 comments on commit dd37244

Please sign in to comment.