剑指offer--数据流中的中位数

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
import java.util.PriorityQueue;
import java.util.Comparator;
 
public class Solution {
 
    PriorityQueue<Integer> left = new PriorityQueue<Integer>(15,new Comparator<Integer>() {
          @Override
          public int compare(Integer o1, Integer o2) {
            // TODO Auto-generated method stub
            return o2-o1;
          }
        }
  );
  PriorityQueue<Integer> right = new PriorityQueue<Integer>();
   
  public void Insert(Integer num) {
    if(left.size() <= right.size()){
      if(left.size() == 0)
        left.offer(num);
      else if(num > right.peek()){
        right.offer(num);
        left.offer(right.poll());
      }else{
        left.offer(num);
      }
    }else{
      if(right.size() == 0){
        if(num < left.peek()){
          right.offer(left.poll());
          left.offer(num);
        }
      }else if(num < left.peek()){
        left.offer(num);
        right.offer(left.poll());
      }else
        right.offer(num);
    }
  }
 
  public Double GetMedian() {
    if(left.size() == right.size())
      return (double)(left.peek() + right.peek())/2;
    else
      return (double)(left.peek());
  }
 
 
}

用两个堆,一个大顶堆,一个小顶堆。

先往小顶堆里面存数,并保持: 0 <= 小顶堆的size()-大顶堆的size() <= 1

保持两边数量几乎一致就需要在插入的时候进行比较、调整。

返回中位数的时候,如果小顶堆和大顶堆size()相同,就返回他们堆顶元素的平均值;否则返回小顶堆的堆顶元素。

这种方法插入时间复杂度是O(log n),返回中位数的时间复杂度是O(1)

你可能感兴趣的:(剑指offer--数据流中的中位数)