描述
中文English
数字是不断进入数组的,在每次添加一个新的数进入数组的同时返回当前新数组的中位数。
您在真实的面试中是否遇到过这个题? 是
题目纠错
说明
中位数的定义:
- 这里的
中位数
不等同于数学定义里的中位数
。 - 中位数是排序后数组的中间值,如果有数组中有n个数,则中位数为A[(n-1)/2]A[(n−1)/2]。
- 比如:数组A=[1,2,3]的中位数是2,数组A=[1,19]的中位数是1。
样例
样例1
输入: [1,2,3,4,5]
输出: [1,1,2,2,3]
样例说明:
[1] 和 [1,2] 的中位数是 1.
[1,2,3] 和 [1,2,3,4] 的中位数是 2.
[1,2,3,4,5] 的中位数是 3.
样例2
输入: [4,5,1,3,2,6,0]
输出: [4,4,4,3,3,3,3]
样例说明:
[4], [4,5] 和 [4,5,1] 的中位数是 4.
[4,5,1,3], [4,5,1,3,2], [4,5,1,3,2,6] 和 [4,5,1,3,2,6,0] 的中位数是 3.
挑战
时间复杂度为O(nlogn)
问题是求逐个加入数组当前的中位数
刚看题的时候想到了滑动窗口 dequeue(不要急 今天晚上就能刷到那个
做法:
获取中位数,何谓中位数,能够把整个数组一分为二的元素。如何维护两个这样的结构,实时获取当前的最值?
想到用堆。现成的堆就是优先队列
那么问题答案就出来了
每次将元素放在大顶堆里面,然后判断是否需要挪一个元素 或者交换一个元素到小顶堆
(hard其实也没那么难是吧
class Solution {
public:
/**
* @param nums: A list of integers
* @return: the median of numbers
*/
priority_queue<int> maxHeap, minHeap;
int tot;
vector<int> medianII(vector<int> &nums) {
// write your code here
vector<int> ans;
tot = 0;
for (int i = 0; i < nums.size(); i ++) {
add_nums(nums[i]);
ans.push_back(maxHeap.top());
}
return ans;
}
void add_nums(int x) {
maxHeap.push(x);
if (tot % 2 == 0) {
if (minHeap.empty()) {
tot ++;
return;
} else {
if (maxHeap.top() > -minHeap.top()) {
int maxn = maxHeap.top();
int minn = minHeap.top();
maxHeap.pop();
minHeap.pop();
maxHeap.push(-minn);
minHeap.push(-maxn);
}
}
} else {
minHeap.push(-maxHeap.top());
maxHeap.pop();
}
tot ++;
}
};