LINTCODE——滑动窗口的中位数
思路:跟数据流中位数的中位数一样(我之前发的数据流中位数不是用堆来实现的),建立两个堆,left存放数组的前半部分,right存放后半部分,则中位数就为left的最大值;
class Solution {
public:
/*
* @param nums: A list of integers
* @param k: An integer
* @return: The median of the element inside the window at each moving
*/
vector<int> medianSlidingWindow(vector<int> &nums, int k) {
// write your code here
multiset<int> left,right;
int n = nums.size();
vector<int> res;
if(n == 0)
return res;
bool flag = true;
for(int i = 0 ; i < k ; i++)
{
//建立两个堆,左堆存放数组的前半部分,右堆存放后半部分
build(left,right,flag,nums[i]);
}
res.push_back(*left.rbegin());
for(int i = k ; i < n ;i++)
{
//从堆中删除前一个数;
erasebuild(left,right,flag,nums[i-k]);
build(left,right,flag,nums[i]);
res.push_back(*left.rbegin());
}
return res;
}
void build(multiset<int> &left, multiset<int> &right, bool &flag, int number)
{
if(flag)
{
if(!right.empty() && *right.begin() < number)
{
right.insert(number);
number = *right.begin();
right.erase(right.find(number));
}
left.insert(number);
}
else
{
if( !left.empty() && *left.rbegin() > number)
{
left.insert(number);
number = *left.rbegin();
left.erase(left.find(number));
}
right.insert(number);
}
flag = !flag;
}
void erasebuild(multiset<int> &left, multiset<int> &right, bool &flag, int number)
{
if(left.find(number) != left.end())
{
left.erase(left.find(number));
//如果从左堆删除,则置flag为TRUE,反之为false;
flag = true;
}
else
{
right.erase(right.find(number));
flag = false;
}
}
};