-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
design-an-array-statistics-tracker.cpp
83 lines (73 loc) · 2.18 KB
/
design-an-array-statistics-tracker.cpp
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
// Time: ctor: O(1)
// addNumber: O(logn)
// removeFirstAddedNumber: O(logn)
// getMean: O(1)
// getMedian: O(1)
// getMode: O(1)
// Space: O(n)
// deque, freq table, bst
class StatisticsTracker {
public:
StatisticsTracker() {
}
void addNumber(int number) {
total_ += number;
dq_.emplace_back(number);
update(number, +1);
if (empty(bst2_) || *begin(bst2_) <= number) {
bst2_.emplace(number);
} else {
bst1_.emplace(number);
}
rebalance();
}
void removeFirstAddedNumber() {
const int number = dq_.front(); dq_.pop_front();
total_ -= number;
update(number, -1);
if (bst2_.count(number)) {
bst2_.erase(bst2_.find(number));
} else {
bst1_.erase(bst1_.find(number));
}
rebalance();
}
int getMean() {
return total_ / size(dq_);
}
int getMedian() {
return *begin(bst2_);
}
int getMode() {
return *begin(rbegin(freq_to_nums_)->second);
}
private:
void update(int number, int d) {
if (num_to_freq_.count(number)) {
freq_to_nums_[num_to_freq_[number]].erase(freq_to_nums_[num_to_freq_[number]].find(number));
if (empty(freq_to_nums_[num_to_freq_[number]])) {
freq_to_nums_.erase(num_to_freq_[number]);
}
}
num_to_freq_[number] += d;
if (!num_to_freq_[number]) {
num_to_freq_.erase(number);
} else {
freq_to_nums_[num_to_freq_[number]].emplace(number);
}
}
void rebalance() {
if (size(bst2_) == size(bst1_) + 2) {
bst1_.emplace(*begin(bst2_));
bst2_.erase(begin(bst2_));
} else if (size(bst2_) + 1 == size(bst1_)) {
bst2_.emplace(*prev(end(bst1_)));
bst1_.erase(prev(end(bst1_)));
}
}
int64_t total_ = 0;
deque<int> dq_;
unordered_map<int, int> num_to_freq_;
map<int, multiset<int>> freq_to_nums_;
multiset<int> bst1_, bst2_;
};