forked from neetcode-gh/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
2421-number-of-good-paths.kt
62 lines (54 loc) · 1.81 KB
/
2421-number-of-good-paths.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
class Solution {
class UnionFind(val n: Int) {
val parent = IntArray (n) { it }
val size = IntArray (n) { 1 }
fun find(i: Int): Int {
if (i != parent[i])
parent[i] = find(parent[i])
return parent[i]
}
fun union(a: Int, b: Int): Boolean {
val pa = find(a)
val pb = find(b)
if (pa == pb) return false
if (size[pa] > size[pb]) {
parent[pb] = pa
size[pa] += size[pb]
} else {
parent[pa] = pb
size[pb] += size[pa]
}
return true
}
}
fun numberOfGoodPaths(vals: IntArray, edges: Array<IntArray>): Int {
val adj = HashMap<Int, MutableList<Int>>().apply {
for ((a, b) in edges) {
this[a] = getOrDefault(a, mutableListOf<Int>()).apply { add(b) }
this[b] = getOrDefault(b, mutableListOf<Int>()).apply { add(a) }
}
}
val valueToIndex = TreeMap<Int, MutableList<Int>>().apply {
for ((i, v) in vals.withIndex()) {
this[v] = getOrDefault(v, mutableListOf<Int>()).apply { add(i) }
}
}
var res = 0
val uf = UnionFind(vals.size)
valueToIndex.keys.forEach { value ->
valueToIndex[value]?.forEach { i ->
adj[i]?.forEach { nei ->
if (vals[nei] <= vals[i])
uf.union(nei, i)
}
}
val count = HashMap<Int, Int>()
valueToIndex[value]?.forEach { i ->
val value = uf.find(i)
count[value] = count.getOrDefault(value, 0) + 1
res += count[value] ?: 0
}
}
return res
}
}