随时找到数据流的中位数

在这里插入图片描述
在这里插入图片描述

分析

这里观察示例,如果数据流为空取中位数返回值为-1
取一个有序序列的中位数,可以从中位数的位置将左右两部分看成是左边部分是一个大根堆,右边部分是一个小根堆,通过维持两个堆来获取中位数
1、如果大根堆和小根堆的大小相等,那么先把数加入小根堆,然后弹出小根堆的堆顶元素加入大根堆
2、如果大根堆和小根堆的大小不想等(大根堆比小根堆多一个),先把元素加入大根堆,然后弹出大根堆的元素加入小根堆
3、如果两个堆的大小相等,那么中位数就是两个堆顶元素相加除以2,如果不想等,中位数就是大根堆的堆顶元素。

import java.util.*;


public class Solution {
    /**
     * the medians
     * @param operations int整型二维数组 ops
     * @return double浮点型一维数组
     */
     public double[] flowmedian (int[][] operations) {
        //小根堆
        PriorityQueue<Integer> smallHeap = new PriorityQueue<>();
        //大根堆
        PriorityQueue<Integer> bigHeap = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        List<Double> list = new ArrayList<>();
        for(int[] operation: operations) {
          int o = operation[0];
            switch (o) {
                //添加操作
                case 1:
                    //获取添加的数据
                    int num = operation[1];
                    //如果大根堆与小根堆的大小相同,则先将数据添加到小根堆中,在从小根堆中弹出一个数添加到大根堆中
                    if(smallHeap.size() == bigHeap.size()) {
                       smallHeap.add(num);
                        bigHeap.add(smallHeap.poll());
                    } else {//如果不相等,直接添加到小根堆中
                        bigHeap.add(num);
                        smallHeap.add(bigHeap.poll());
                    }
                    break;
                    //获取中位数的操作
                case 2:
                    if(bigHeap.size() == 0 && smallHeap.size() == 0) {
                        list.add(-1.0);
                    } else 
                    if(bigHeap.size() == smallHeap.size()) {
                        list.add((bigHeap.peek() + smallHeap.peek()) / 2.0);
                    } else {
                        list.add(bigHeap.peek() * 1.0);
                    }
                    break;
            }
        }
        double[] res = new double[list.size()];
        int i = 0;
        for (double d : list) {
            res[i++] = d;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值