-
Notifications
You must be signed in to change notification settings - Fork 0
/
dailycoding033.cpp
85 lines (71 loc) · 2.15 KB
/
dailycoding033.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
84
85
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using std::vector;
using std::greater;
using std::priority_queue;
using std::cout;
using std::endl;
/*
* This problem was asked by Microsoft.
*
* Compute the running median of a sequence of numbers.
* That is, given a stream of numbers, print out the median
* of the list so far on each new element.
*
*
* Solution: Use two heaps, one max heap and one min heap
*
* We know that we find the median using the middle number or middle
* two numbers, so using the max heap we store the left middle num
* and using the min heap we store the right middle num. We prioritize adding
* to the max heap over the min heap but the solution would also work vice versa.
* Whenever the max heap contains more elements, offer the max to the min heap,
* and if the min heap contains more elements than the max heap, offer the min.
*
* After balancing the heaps, if the max heap ends up with one more element
* than the min heap, the top is the median and we are done. If the heaps are
* perfectly balanced (equal in size), then the median is the average of the
* two tops.
*
* */
class RunningMedian {
// min and max heaps
priority_queue<int> lo;
priority_queue<int, vector<int>, greater<int>> hi;
public:
// pushes next datastream element onto heaps
void add_num(int k) {
lo.push(k); // always push to max heap first
hi.push(lo.top());
lo.pop(); // balance the heaps
if (lo.size() < hi.size()) { // makes sure that lo has the most elements only
lo.push(hi.top());
hi.pop();
}
}
// finds the running median
double find_median() {
return (lo.size() > hi.size())? (double)lo.top() : (lo.top() + hi.top()) * 0.5;
}
// solve the problem
template<typename T, size_t N>
void run(T (&a)[N]) {
cout << "Running medians of: [ ";
for (int i = 0; i < N; i++) {
cout << a[i] << " ";
}
cout << "]" << endl;
for (int i = 0; i < N; i++) {
add_num(a[i]);
cout << find_median() << endl;
}
}
};
int main() {
int test[6] = {41, 35, 62, 5, 97, 108};
RunningMedian solution;
solution.run(test);
return 0;
}