数据流中的中位数

2019-11-13  本文已影响0人  ElricTang

《剑指offer》刷题笔记。如有更好解法,欢迎留言。

关键字: 进制转化 队列 排序

题目描述:

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

思路:

创建两个队列 left 和 right
1. 左右队列都为空时,将num随便放入左或者右。


2. 左队列为空,右队列不为空
3. 右队列为空,左队列不为空
4. 左右队列都不为空

最后,将左右队列合并就能得到有序数据流。中位数按照奇偶情况获取。

let left = [];
let right = [];

function Insert(num)
{
  // 左右队列为空
  if(left.length === 0 && right.length === 0){
    left.push(num);
  }
  // 左队列为空,右队列不为空
  else if(left.length === 0 && right.length !== 0){
    if(num < right[0]){
      left.push(num);
    }else{
      left.push(right.shift());
      right.unshift(num);
    }
  }
  // 右队列为空,左队列不为空
  else if(left.length !== 0 && right.length === 0){
    if(num > left[left.length-1]){
      right.unshift(num);
    }else{
      right.unshift(left.pop());
      left.push(num);
    }
  }
  // 两个队列都不为空
  else{
    if(num > left[left.length-1] && num < right[0]){
      left.push(num);
    }else if(num < left[left.length-1] && num < right[0]){
      right.unshift(left.pop());
      left.push(num);
    }else if(num > left[left.length-1] && num > right[0]){
      left.push(right.shift());
      right.unshift(num);
    }
  }
  
  // 修正左右队列
  if(left[0]>left[left.length-1]){
    left.unshift(left.pop());
  }
  if(right[0]>right[right.length-1]){
    right.push(right.shift());
  }
}
function GetMedian(){
  let temp = [...left,...right];
  let l = temp.length;
  if(l%2 === 0){
    return (temp[Math.floor(l/2)]+temp[Math.floor(l/2)-1])/2;
  }else{
    return temp[Math.floor(l/2)];
  }
}
上一篇下一篇

猜你喜欢

热点阅读