forked from javadev/LeetCode-in-Kotlin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSolution.kt
63 lines (58 loc) · 2.21 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
package g0201_0300.s0218_the_skyline_problem
// #Hard #Array #Heap_Priority_Queue #Ordered_Set #Divide_and_Conquer #Segment_Tree
// #Binary_Indexed_Tree #Line_Sweep #2022_10_25_Time_365_ms_(93.14%)_Space_45.7_MB_(93.71%)
import java.util.TreeMap
class Solution {
fun getSkyline(blds: Array<IntArray>): List<List<Int>> {
val ans = ArrayList<List<Int>>()
if (blds.isEmpty()) {
return ans
}
val totalBuildings = blds.size
val buildings = Array<Building?>(totalBuildings * 2) { null }
var idx = 0
for (building in blds) {
buildings[idx] = Building(building[0], building[2], true)
buildings[idx + 1] = Building(building[1], building[2], false)
idx += 2
}
buildings.sort()
val skyline = TreeMap<Int, Int>()
skyline[0] = 1
var prevMaxHeight = 0
for (building in buildings) {
if (building == null) {
continue
}
val height = building.height
if (building.isStart) {
skyline[height] = 1 + (skyline[height] ?: 0)
} else {
skyline[height] = (skyline[height] ?: 1) - 1
if (skyline[height] == 0) skyline.remove(height)
}
val xCoor = building.xCoor
val curMaxHeight = skyline.lastKey()
if (prevMaxHeight != curMaxHeight) {
ans.add(arrayListOf(xCoor, curMaxHeight))
prevMaxHeight = curMaxHeight
}
}
return ans
}
private class Building(val xCoor: Int, val height: Int, val isStart: Boolean) : Comparable<Building> {
override fun compareTo(other: Building): Int {
return COMPARATOR.compare(this, other)
}
private companion object {
private val COMPARATOR = Comparator<Building> { a, b ->
when {
a.xCoor != b.xCoor -> a.xCoor.compareTo(b.xCoor)
a.isStart && b.isStart -> b.height.compareTo(a.height)
!(a.isStart || b.isStart) -> a.height.compareTo(b.height)
else -> if (a.isStart) -1 else 1
}
}
}
}
}