[路飞]_295. 数据流的中位数

310 阅读2分钟

题目地址
B站视频

题目描述

中位数是有序列表中间的数。如果列表长度是偶数,中位数则是中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

  • void addNum(int num) - 从数据流中添加一个整数到数据结构中。
  • double findMedian() - 返回目前所有元素的中位数。 示例:
addNum(1)
addNum(2)
findMedian() -> 1.5
addNum(3) 
findMedian() -> 2

ES6数组的扩展

实例方法:find()findIndex()
find()该方法主要应用于查找第一个符合条件的数组元素。它的参数是一个回调函数。在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。如果没有符合条件的元素,返回值为undefined。 以下代码在myArr数组中查找元素值大于4的元素,找到后立即返回。返回的结果为查找到的元素:

const myArr = [1, 2, 3, 4, 5, 6];
var v = myArr.find(value => value > 4);
console.log('v', v); // 5

没有符合的元素,就返回undefined

const myArr = [1, 2, 3, 4, 5, 6];
var v = myArr.find(value => value > 40);
console.log('v', v); // undefined

回调函数有三个参数。

value:当前的数组元素。
index:当前索引值。
arr:被查找得数组。
查找索引值为4的元素:

const myArr = [1, 2, 3, 4, 5, 6];
var v = myArr.find((value, index,arr) => {
    return index == 4;
})
console.log('v', v); // 5

findIndex()
findIndex()与find()的使用方法相同,只是当条件为true时findIndex()返回的是索引值,而find()返回的是元素。如果没有符合条件元素时findIndex()返回的是-1,而find()返回的是undefined。findIndex()当中的回调函数也是接收三个参数,与find()相同。

const bookArr = [
    {
        id:1,
        bookName: "sanguo"
    },{
        id:2,
        bookName: "shuihu"
    },{
        id:3,
        bookName: "honglou"
    },{
        id:4,
        bookName: "xiyou"
    }
];
var i = bookArr.findIndex((value) => value.id == 4);
console.log('i', i); // 3
var i2 = bookArr.findIndex((value) => value.id == 100);
console.log('i2', i2); // -1

解题思路

  • 申明一个数组arr
  • 通过Array.findIndex去判断当前的num值是否在arr中,并返回对应得下标
  • 如果不存在arr中就返回-1,然后就push(num).
  • 如果存在,就用数组的Array.splice()方法,把num插入到返回的对应下标前面
  • 最后要根据数组的长度来判断中位数。区分奇数偶数。

代码

var MedianFinder = function() {
    this.arr = [];
};
MedianFinder.prototype.addNum = function(num) {
    let index = this.arr.findIndex((a) => a >= num);
    if(index === -1){
        this.arr.push(num);
    } else{
        this.arr.splice(index, 0, num);
    }
};
MedianFinder.prototype.findMedian = function() {
    if(this.arr.length % 2){
        return this.arr[this.arr.length / 2 | 0]
    }
    return (this.arr[this.arr.length / 2] + this.arr[this.arr.length / 2 -1]) / 2
};