-
Notifications
You must be signed in to change notification settings - Fork 111
/
sliding-window-median.cc
50 lines (50 loc) · 1.42 KB
/
sliding-window-median.cc
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
// Sliding Window Median
class Solution {
public:
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
vector<double> r;
multiset<int> a(nums.begin(), nums.begin()+k);
auto mid = next(a.begin(), (k-1)/2);
for (int i = k; ; i++) {
r.push_back((double(*mid)+*next(mid, 1-k%2))/2);
if (i == nums.size()) break;
a.insert(nums[i]);
if (nums[i] < *mid) --mid;
if (nums[i-k] <= *mid) ++mid;
a.erase(a.lower_bound(nums[i-k]));
}
return r;
}
};
///
class Solution {
vector<int> fenwick;
void add(int x, int n, int v) {
for (; x < n; x |= x+1)
fenwick[x] += v;
}
int select(int k, int n) {
int r = -1;
for (int x = 1<<31-__builtin_clz(n); x; x >>= 1)
if (r+x < n && fenwick[r+x] <= k)
k -= fenwick[r += x];
return r+1;
}
public:
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
vector<double> r;
vector<int> a = nums;
int n = nums.size();
fenwick.assign(n, 0);
sort(a.begin(), a.end());
for (int i = 0; i < k; i++)
add(lower_bound(a.begin(), a.end(), nums[i])-a.begin(), n, 1);
for (int i = k; i <= nums.size(); i++) {
r.push_back(0.5*(double(a[select((k-1)/2, n)])+a[select(k/2, n)]));
add(lower_bound(a.begin(), a.end(), nums[i-k])-a.begin(), n, -1);
if (i < nums.size())
add(lower_bound(a.begin(), a.end(), nums[i])-a.begin(), n, 1);
}
return r;
}
};