-
-
Notifications
You must be signed in to change notification settings - Fork 8.8k
/
Copy pathSolution.go
92 lines (87 loc) · 2.05 KB
/
Solution.go
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
type MKAverage struct {
lo, mid, hi *redblacktree.Tree
q []int
m, k, s int
size1, size3 int
}
func Constructor(m int, k int) MKAverage {
lo := redblacktree.NewWithIntComparator()
mid := redblacktree.NewWithIntComparator()
hi := redblacktree.NewWithIntComparator()
return MKAverage{lo, mid, hi, []int{}, m, k, 0, 0, 0}
}
func (this *MKAverage) AddElement(num int) {
merge := func(rbt *redblacktree.Tree, key, value int) {
if v, ok := rbt.Get(key); ok {
nxt := v.(int) + value
if nxt == 0 {
rbt.Remove(key)
} else {
rbt.Put(key, nxt)
}
} else {
rbt.Put(key, value)
}
}
if this.lo.Empty() || num <= this.lo.Right().Key.(int) {
merge(this.lo, num, 1)
this.size1++
} else if this.hi.Empty() || num >= this.hi.Left().Key.(int) {
merge(this.hi, num, 1)
this.size3++
} else {
merge(this.mid, num, 1)
this.s += num
}
this.q = append(this.q, num)
if len(this.q) > this.m {
x := this.q[0]
this.q = this.q[1:]
if _, ok := this.lo.Get(x); ok {
merge(this.lo, x, -1)
this.size1--
} else if _, ok := this.hi.Get(x); ok {
merge(this.hi, x, -1)
this.size3--
} else {
merge(this.mid, x, -1)
this.s -= x
}
}
for ; this.size1 > this.k; this.size1-- {
x := this.lo.Right().Key.(int)
merge(this.lo, x, -1)
merge(this.mid, x, 1)
this.s += x
}
for ; this.size3 > this.k; this.size3-- {
x := this.hi.Left().Key.(int)
merge(this.hi, x, -1)
merge(this.mid, x, 1)
this.s += x
}
for ; this.size1 < this.k && !this.mid.Empty(); this.size1++ {
x := this.mid.Left().Key.(int)
merge(this.mid, x, -1)
this.s -= x
merge(this.lo, x, 1)
}
for ; this.size3 < this.k && !this.mid.Empty(); this.size3++ {
x := this.mid.Right().Key.(int)
merge(this.mid, x, -1)
this.s -= x
merge(this.hi, x, 1)
}
}
func (this *MKAverage) CalculateMKAverage() int {
if len(this.q) < this.m {
return -1
}
return this.s / (this.m - 2*this.k)
}
/**
* Your MKAverage object will be instantiated and called as such:
* obj := Constructor(m, k);
* obj.AddElement(num);
* param_2 := obj.CalculateMKAverage();
*/