开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第34天,点击查看活动详情
中位数是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
- 例如
arr = [2,3,4]的中位数是3。 - 例如
arr = [2,3]的中位数是(2 + 3) / 2 = 2.5。
实现 MedianFinder 类:
-
MedianFinder()初始化MedianFinder对象。 -
void addNum(int num)将数据流中的整数num添加到数据结构中。 -
double findMedian()返回到目前为止所有元素的中位数。与实际答案相差10^-5以内的答案将被接受。
示例 1:
输入
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
[[], [1], [2], [], [3], []]
输出
[null, null, null, 1.5, null, 2.0]
解释
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1); // arr = [1]
medianFinder.addNum(2); // arr = [1, 2]
medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
medianFinder.addNum(3); // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0
提示:
-10^5 <= num <= 10^5- 在调用
findMedian之前,数据结构中至少有一个元素 - 最多
5 * 10^4次调用addNum和findMedian
思路
由题目可知,中位数是有序整数列的中间值,所以求中位数之前我们要保证数列有序。我们可以维护一个升序数列nums,addNum是往nums中添加整数num,我们可以用二分查找小于等于num的最大值,在他之后插入num。findMedian方法就很简单了,只需要按要求求中位数就可以了,代码如下。
解题
var MedianFinder = function () {
this.nums = [];
};
/**
* @param {number} num
* @return {void}
*/
MedianFinder.prototype.addNum = function (num) {
let left = 0;
let right = this.nums.length - 1;
while (left <= right) {
const mid = (left + right) >> 1;
if (this.nums[mid] > num) {
right = mid - 1;
} else if (this.nums[mid] < num) {
left = mid + 1;
} else {
left = mid;
break;
}
}
this.nums.splice(left, 0, num);
};
/**
* @return {number}
*/
MedianFinder.prototype.findMedian = function () {
const n = this.nums.length - 1;
const a = n >> 1;
const b = a + (n & 1);
return (this.nums[a] + this.nums[b]) / 2;
};
/**
* Your MedianFinder object will be instantiated and called as such:
* var obj = new MedianFinder()
* obj.addNum(num)
* var param_2 = obj.findMedian()
*/