forked from neetcode-gh/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
0352-data-stream-as-disjoint-intervals.kt
98 lines (75 loc) · 2.39 KB
/
0352-data-stream-as-disjoint-intervals.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
90
91
92
93
94
95
96
97
98
// Using TreeSet and linear scan in getIntervals() method
class SummaryRanges() {
val ranges = TreeSet<Int>()
fun addNum(value: Int) {
ranges.add(value)
}
fun getIntervals(): Array<IntArray> {
val res = LinkedList<IntArray>()
ranges.forEach {
if (res.isNotEmpty() && res.peekLast()[1] + 1 == it)
res.peekLast()[1] = it
else
res.addLast(intArrayOf(it, it))
}
return res.toTypedArray()
}
}
// Using TreeMap and binary search scan in getIntervals() method, small optimization technically but still same time complexity as above solution
class SummaryRanges() {
val rgs = TreeMap<Int, IntArray>()
fun addNum(v: Int) {
if (rgs.containsKey(v)) return
val l = rgs.lowerKey(v)
val h = rgs.higherKey(v)
if (l != null && h != null && rgs.get(l)!![1] + 1 == v && h == v + 1 ) {
rgs.get(l)!![1] = rgs.get(h)!![1]
rgs.remove(h)
} else if (l != null && rgs.get(l)!![1] + 1 >= v) {
rgs.get(l)!![1] = maxOf(v, rgs.get(l)!![1])
} else if (h != null && h == v + 1) {
rgs.put(v, intArrayOf(v, rgs.get(h)!![1]))
rgs.remove(h)
} else {
rgs.put(v, intArrayOf(v, v))
}
}
fun getIntervals() = rgs.values.toTypedArray()
}
// Using Union Find
class SummaryRanges() {
val dsu = DSU()
fun addNum(v: Int) {
if (dsu.exists(v)) return
dsu.add(v)
dsu.union(v, v - 1)
dsu.union(v, v + 1)
}
fun getIntervals() = dsu.getIntervals()
}
class DSU {
val parent = HashMap<Int, Int>()
val intervals = TreeMap<Int, IntArray>()
fun getIntervals() = intervals.values.toTypedArray()
fun exists(x: Int) = x in parent
fun add(x: Int) {
parent[x] = x
intervals[x] = intArrayOf(x, x)
}
fun find(x: Int): Int {
parent[x]?: return -1
if (parent[x]!! != x)
parent[x] = find(parent[x]!!)
return parent[x]!!
}
fun union(x: Int, y: Int) {
val px = find(x)
val py = find(y)
if (px == -1 || py == -1) return
val newX = minOf(intervals[py]!![0], intervals[px]!![0])
val newY = maxOf(intervals[py]!![1], intervals[px]!![1])
parent[px] = py
intervals[py] = intArrayOf(newX, newY)
intervals.remove(px)
}
}