[每日一道小算法(七十一)][进制转化] 数据流中的中位数(剑指offer)

前言:
不能因现实复杂而放弃梦想,不能因理想遥远而放弃追求”,因为——“历史只会眷顾坚定者、奋进者、搏击者,而不会等待犹豫者、懈怠者、畏难者。"

题目描述

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

解题思路

这道题我是使用优先队列来使用。分别使用一个大顶堆和小顶堆进行保存数据。这样直接说可能不会懂。举个例子来说一下思路吧。
需要求的是中位数,如果我将 1 2 3 4 5 6 7 8定为最终的数据流
此时的中位数是4+5求均值。为什么是4,为什么是5
利用队列我们就可以看得很清楚,4是前半部分最大的值,肯定是维系在大顶堆
而5是后半部分的最小值,肯定是维系在小顶堆。
所以问题就解决了:
使用小顶堆存大数据,使用大顶堆存小数据。这样堆顶取出就是中位数了。

代码样例

package com.asong.leetcode.GetMedian;

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;

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

    //大顶堆存储小数据
    private PriorityQueue<Integer> low = new PriorityQueue<Integer>(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2.compareTo(o1);
        }
    });
    //小顶堆存储大数据
    private PriorityQueue<Integer> high = new PriorityQueue<Integer>();
    //奇偶个数判断
    private int n = 0;

    public void Insert(Integer num) {
        //偶数
        if(n%2==0)
        {
            low.add(num);
            high.add(low.poll());
        }else {
            high.add(num);
            low.add(high.poll());
        }
        n++;
    }

    public Double GetMedian() {
        if(n%2==0)
        {
            return ((low.peek()+high.peek())/2.0);
        }else {
            return (double)high.peek();
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        solution.Insert(1);
        solution.Insert(2);
        solution.Insert(3);
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值