class Solution {
public:
vector<double> res;
multiset<int> left, right;
int ksize;
double getmedian()
{
if(ksize % 2) return *right.begin(); //计数返会右边第一个数,因为右边数比左边数多1
return (((double)*right.begin() + *left.rbegin())) / 2; //偶数返回两边最大和最小值除以2的结果
}
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
ksize = k;
for(int i = 0; i < k; i++) right.insert(nums[i]);
//左分k / 2个数, 右分k - k / 2 个数
for(int i = 0; i < k / 2; i++) {
left.insert(*right.begin());
right.erase(right.begin());
}
//第一次记录窗口的中位数
res.push_back(getmedian());
//枚举[k, nums.size()] 区间数插入窗口
for(int i = k; i < nums.size(); i++){
int x = nums[i]; //当前要进入窗口的数
int y = nums[i - k]; //窗口的第一个数,最左边的数
//新数插入左区间或者右区间
if(x >= *right.begin()) right.insert(x);
else left.insert(x);
//判断需要被划出窗口的数是左边还是右边
if(y >= *right.begin()) right.erase(right.find(y));
else left.erase(left.find(y));
//左边数多了,将左边的数放入右边
while(left.size() > right.size()){
right.insert(*left.rbegin());
left.erase(left.find(*left.rbegin()));
}
//维护右边数比左边数多1的性质
while(right.size() > left.size() + 1){
left.insert(*right.begin());
right.erase(right.begin());
}
res.push_back(getmedian());
}
return res;
}
};
力扣每日一题【滑动窗口中位数】
最新推荐文章于 2023-03-16 11:25:08 发布