LeetCode.295 数据流的中位数

原题
https://leetcode-cn.com/problems/find-median-from-data-stream/
在这里插入图片描述

思路

使用两个优先队列 PriorityQueue
一个用来存储中位数前边的数据,要求从大到小排列,命名为queueMin
一个用来存储中位数后边的数据,要求从小到大排列,命名为queueMax
这样两个queue.peek()用来计算中位数
下面讨论列表的奇偶性

  • 奇数
    • 右边多存储一个元素,也就是queueMin.size() + 1 == queueMax.size()
    • 得到的中位数就是queueMax.peek()
  • 偶数
    • 左边和右边存储的元素数量一致,也就是 queueMin.size() == queueMax.size()
    • 得到的中位数就是(queueMin.peek() + queueMax.peek()) / 2.0

插入元素的时候
queueMax.isEmpty()
num >= queueMax.peek()
就往右边队列queueMax插入数据
其余往左边插入
注意:插入数据的同时还要维护queueMin.size()queueMax.size()
(1)向右边queueMax插入的时候,queueMax.size() > queueMin.size()+1的时候,就要把queueMax.poll()添加到queueMin
(2)向左边queueMin插入的时候,queueMin.size() > queueMax.size()的时候,就要把queueMin.poll()添加到queueMax


题解

package com.ivydad.test;

import java.util.PriorityQueue;

/**
 * @Author: kun.zhang@ivydad.com
 * @Description: TODO
 * @DateTime: 2021/8/27 6:03 下午
 **/
public class MedianFinder {

//    存储中位数前边那一部分,从大到小排列
    PriorityQueue<Integer> queueMin;
//    存储中位数后边那一部分,从小到大排列
    PriorityQueue<Integer> queueMax;

    public MedianFinder() {
        queueMin = new PriorityQueue<>((a,b) -> b-a);
        queueMax = new PriorityQueue<>((a,b) -> a-b);
    }

//    奇数:后段队列多一个
//    偶数:两个队列等长
    public void addNum(int num) {
        if (queueMax.isEmpty() || queueMax.peek() <= num) {
            queueMax.offer(num);
            if (queueMax.size() > queueMin.size() + 1) {
                queueMin.offer(queueMax.poll());
            }
        } else {
            queueMin.offer(num);
            if (queueMin.size() > queueMax.size()) {
                queueMax.offer(queueMin.poll());
            }
        }
    }

    public double findMedian() {
        if (queueMin.size() == queueMax.size()) {
            return (queueMin.peek() + queueMax.peek())/2.0;
        } else {
            return queueMax.peek();
        }
    }

    public static void main(String[] args) {
        MedianFinder medianFinder = new MedianFinder();
        medianFinder.addNum(1);
        medianFinder.addNum(2);
        System.out.println(medianFinder.findMedian());
        medianFinder.addNum(3);
        System.out.println(medianFinder.findMedian());
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

难过的风景

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值