给定一个包含 n 个整数的数组,和一个大小为 k 的滑动窗口,从左到右在数组中滑动这个窗口,找到数组中每个窗口内的中位数。(如果数组个数是偶数,则在该窗口排序数字后,返回第 N/2 个数字。)
样例:
对于数组 [1,2,7,8,5], 滑动大小 k = 3 的窗口时,返回 [2,7,7]
最初,窗口的数组是这样的:
[ | 1,2,7 | ,8,5] , 返回中位数 2;
接着,窗口继续向前滑动一次。
[1, | 2,7,8 | ,5], 返回中位数 7;
接着,窗口继续向前滑动一次。
[1,2, | 7,8,5 | ], 返回中位数 7;
挑战:
时间复杂度为 O(nlog(n))
#ifndef C360_H
#define C360_H
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
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
vector<int> v;
if (nums.empty() || k == 0)
return v;
if (k == 1)
return nums;
int len = nums.size();
if (k >= len)
{
sort(nums.begin(), nums.end());
v.push_back(nums.size() % 2 == 0 ? nums[nums.size() / 2 - 1] : nums[nums.size() / 2]);
return v;
}
multiset<int> rset, lset;
for (int i = 0; i < len; ++i)
{
if (i >= k)
{
if (lset.count(nums[i - k]))
lset.erase(lset.find(nums[i - k]));
else
rset.erase(rset.find(nums[i - k]));
}
if (lset.size() <= rset.size())
{
if (rset.empty() || nums[i] <= *rset.begin())
lset.insert(nums[i]);
else
{
lset.insert(*rset.begin());
rset.erase(rset.begin());
rset.insert(nums[i]);
}
}
else
{
if (nums[i] >= *lset.rbegin())
rset.insert(nums[i]);
else
{
rset.insert(*lset.rbegin());
lset.erase(--lset.end());
lset.insert(nums[i]);
}
}
if (i + 1 >= k)
{
v.push_back(*lset.rbegin());
}
}
return v;
}
};
#endif