问题
思路
参考:[C++ two multiset solution]
代码思路非常的清晰。
不能继续使用priority_queue的原因是,删除操作不方便。
所以,改用multiset,优点是,插入删除都很块,并且有序。这样可以维护前半部分和后半部分,其实map也可以实现这个功能。他们都不需要随机访问,但是map不能存重复元素。
这个题很多坑:
- 删除的时候,不能用元素值,因为可能会重复。否则,会删掉多个。只能用迭代器
- 其次,max必须比min多一个才行,这样才能保证整体的有序性!否则,如果按照之前的题目则不行。或者,你直接用之前的办法调整有序也可以。
代码
class Solution {
public:
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
multiset<int> min;
multiset<int> max;
vector<double> ret;
int sz = nums.size();
for( int i = 0; i < sz; ++i ) {
// insert new number
if( max.empty() || nums[i] > *max.begin() ) max.insert( nums[i] );
else min.insert( nums[i] );
// remove number out of window
if( i >= k ) {
if( nums[i-k] >= *max.begin() )
max.erase( max.find(nums[i-k]) );
else
min.erase( min.find(nums[i-k]) );
}
// balance the size of 2 sets
while( max.size () < min.size() ){
max.insert( *min.rbegin() );
min.erase( --min.end() );
}
while( max.size() - 1 > min.size() ) {
min.insert(*max.begin());
max.erase( max.begin() );
}
// push back median
if( i < k-1 ) continue;
if( k & 0x1 ) {
ret.push_back( *max.begin() );
}else {
double t = ( (double)*min.rbegin() + *max.begin() ) * 1.0 /2;
ret.push_back(t);
}
}
return ret;
}
};