Skip to content

feat: add solutions to lc problem: No.0815 #3531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
370 changes: 220 additions & 150 deletions solution/0800-0899/0815.Bus Routes/README.md

Large diffs are not rendered by default.

373 changes: 202 additions & 171 deletions solution/0800-0899/0815.Bus Routes/README_EN.md

Large diffs are not rendered by default.

68 changes: 32 additions & 36 deletions solution/0800-0899/0815.Bus Routes/Solution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,45 @@ class Solution {
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);

unordered_map<int, vector<int>> g;
for (int i = 0; i < routes.size(); i++) {
for (int stop : routes[i]) {
g[stop].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);

if (!g.contains(source) || !g.contains(target)) {
return -1;
}

queue<pair<int, int>> q;
unordered_set<int> visBus;
unordered_set<int> visStop;
q.push({source, 0});
visStop.insert(source);

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);
auto [stop, busCount] = q.front();
q.pop();

if (stop == target) {
return busCount;
}

for (int bus : g[stop]) {
if (!visBus.contains(bus)) {
for (int nextStop : routes[bus]) {
if (!visStop.contains(nextStop)) {
visBus.insert(bus);
visStop.insert(nextStop);
q.push({nextStop, busCount + 1});
}
}
}
}
++ans;
}

return -1;
}
};
};
56 changes: 25 additions & 31 deletions solution/0800-0899/0815.Bus Routes/Solution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,39 @@ public int NumBusesToDestination(int[][] routes, int source, int target) {
return 0;
}

Dictionary<int, HashSet<int>> stopToRoutes = new Dictionary<int, HashSet<int>>();
List<HashSet<int>> routeToStops = new List<HashSet<int>>();

Dictionary<int, List<int>> g = new Dictionary<int, List<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>();
if (!g.ContainsKey(stop)) {
g[stop] = new List<int>();
}
stopToRoutes[stop].Add(i);
g[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);
if (!g.ContainsKey(source) || !g.ContainsKey(target)) {
return -1;
}

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);
Queue<int[]> q = new Queue<int[]>();
HashSet<int> visBus = new HashSet<int>();
HashSet<int> visStop = new HashSet<int>();
q.Enqueue(new int[]{source, 0});
visStop.Add(source);

while (q.Count > 0) {
int[] current = q.Dequeue();
int stop = current[0], busCount = current[1];
if (stop == target) {
return busCount;
}
foreach (int bus in g[stop]) {
if (!visBus.Contains(bus)) {
foreach (int nextStop in routes[bus]) {
if (!visStop.Contains(nextStop)) {
visBus.Add(bus);
visStop.Add(nextStop);
q.Enqueue(new int[]{nextStop, busCount + 1});
}
}
}
Expand Down
73 changes: 34 additions & 39 deletions solution/0800-0899/0815.Bus Routes/Solution.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,45 @@ 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)
}

g := make(map[int][]int)
for i, route := range routes {
for _, stop := range route {
g[stop] = append(g[stop], i)
}
}
q := d[source]
vis := map[int]bool{}
for _, v := range d[source] {
vis[v] = true

if g[source] == nil || g[target] == nil {
return -1
}
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)

q := list.New()
q.PushBack([2]int{source, 0})
visBus := make(map[int]bool)
visStop := make(map[int]bool)
visStop[source] = true

for q.Len() > 0 {
front := q.Front()
q.Remove(front)
stop, busCount := front.Value.([2]int)[0], front.Value.([2]int)[1]

if stop == target {
return busCount
}

for _, bus := range g[stop] {
if !visBus[bus] {
visBus[bus] = true
for _, nextStop := range routes[bus] {
if !visStop[nextStop] {
visStop[nextStop] = true
q.PushBack([2]int{nextStop, busCount + 1})
}
}
}
}
ans++
}

return -1
}
}
66 changes: 29 additions & 37 deletions solution/0800-0899/0815.Bus Routes/Solution.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,42 @@ 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);

Map<Integer, List<Integer>> g = new HashMap<>();
for (int i = 0; i < routes.length; i++) {
for (int stop : routes[i]) {
g.computeIfAbsent(stop, 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);

if (!g.containsKey(source) || !g.containsKey(target)) {
return -1;
}

Deque<int[]> q = new ArrayDeque<>();
Set<Integer> visBus = new HashSet<>();
Set<Integer> visStop = new HashSet<>();
q.offer(new int[] {source, 0});
visStop.add(source);

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);
int[] current = q.poll();
int stop = current[0], busCount = current[1];

if (stop == target) {
return busCount;
}
for (int bus : g.get(stop)) {
if (visBus.add(bus)) {
for (int nextStop : routes[bus]) {
if (visStop.add(nextStop)) {
q.offer(new int[] {nextStop, busCount + 1});
}
}
}
}
++ans;
}

return -1;
}
}
}
48 changes: 18 additions & 30 deletions solution/0800-0899/0815.Bus Routes/Solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,23 @@ def numBusesToDestination(
) -> 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
for i, route in enumerate(routes):
for stop in route:
g[stop].append(i)
if source not in g or target not in g:
return -1
q = [(source, 0)]
vis_bus = set()
vis_stop = {source}
for stop, bus_count in q:
if stop == target:
return bus_count
for bus in g[stop]:
if bus not in vis_bus:
vis_bus.add(bus)
for next_stop in routes[bus]:
if next_stop not in vis_stop:
vis_stop.add(next_stop)
q.append((next_stop, bus_count + 1))
return -1
Loading
Loading