-
Notifications
You must be signed in to change notification settings - Fork 21
/
Solution.kt
89 lines (84 loc) · 2.6 KB
/
Solution.kt
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package g0801_0900.s0815_bus_routes
// #Hard #Array #Hash_Table #Breadth_First_Search #Level_2_Day_11_Graph/BFS/DFS
// #2023_03_22_Time_429_ms_(100.00%)_Space_55.8_MB_(100.00%)
import java.util.LinkedList
import java.util.Queue
class Solution {
fun numBusesToDestination(routes: Array<IntArray>, source: Int, target: Int): Int {
if (source == target) {
return 0
}
val targetRoutes: MutableSet<Int> = HashSet()
val queue: Queue<Int> = LinkedList()
val taken = BooleanArray(routes.size)
val graph = buildGraph(routes, source, target, queue, targetRoutes, taken)
if (targetRoutes.isEmpty()) {
return -1
}
var bus = 1
while (queue.isNotEmpty()) {
val size = queue.size
for (i in 0 until size) {
val route = queue.poll()
if (targetRoutes.contains(route)) {
return bus
}
for (nextRoute in graph[route]!!) {
if (!taken[nextRoute]) {
queue.offer(nextRoute)
taken[nextRoute] = true
}
}
}
bus++
}
return -1
}
private fun buildGraph(
routes: Array<IntArray>,
source: Int,
target: Int,
queue: Queue<Int>,
targetRoutes: MutableSet<Int>,
taken: BooleanArray,
): Array<ArrayList<Int>?> {
val len = routes.size
val graph: Array<ArrayList<Int>?> = arrayOfNulls(len)
for (i in 0 until len) {
routes[i].sort()
graph[i] = ArrayList()
var id = routes[i].binarySearch(source)
if (id >= 0) {
queue.offer(i)
taken[i] = true
}
id = routes[i].binarySearch(target)
if (id >= 0) {
targetRoutes.add(i)
}
}
for (i in 0 until len) {
for (j in i + 1 until len) {
if (commonStop(routes[i], routes[j])) {
graph[i]?.add(j)
graph[j]?.add(i)
}
}
}
return graph
}
private fun commonStop(routeA: IntArray, routeB: IntArray): Boolean {
var idA = 0
var idB = 0
while (idA < routeA.size && idB < routeB.size) {
if (routeA[idA] == routeB[idB]) {
return true
} else if (routeA[idA] < routeB[idB]) {
idA++
} else {
idB++
}
}
return false
}
}