leetcode-480-Sliding Window Median

问题

题目:[leetcode-480]

思路

参考:[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;
    }
};

你可能感兴趣的:(LeetCode刷题)