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

Posted le-le

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer:数据流中的中位数相关的知识,希望对你有一定的参考价值。

题意描述

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

解题思路

一、思路一

使用堆排序思想

  1. 建立一个大顶堆与一个小顶堆,大顶堆用来存较小的数,从大到小排列;小顶堆存较大的数,从小到大的顺序排序,显然中位数就是大顶堆的根节点与小顶堆的根节点和的平均数。
  2. 小顶堆中的元素都大于等于大顶堆中的元素,所以每次塞值,并不是直接塞进去,而是从另一个堆中poll出一个最大(最小)的塞值
  3. 当数目为偶数的时候,将这个值插入大顶堆中,再将大顶堆中根节点(即最大值)插入到小顶堆中;
  4. 当数目为奇数的时候,将这个值插入小顶堆中,再讲小顶堆中根节点(即最小值)插入到大顶堆中;
  5. 取中位数的时候,如果当前个数为偶数,显然是取小顶堆和大顶堆根结点的平均值;如果当前个数为奇数,显然是取小顶堆的根节点
	 public class Solution {
        private PriorityQueue<Integer> min = new PriorityQueue<>();	//小顶堆
        private PriorityQueue<Integer> max = new PriorityQueue<>(new Comparator<Integer>() {//大顶堆
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
         //记录数据流个数
        private int count = 0;
        public void Insert(Integer num) {
            count++;	//个数+1
            if(count%2 == 1){	//当数据流为奇数时
                max.offer(num);	//加入大顶堆
                min.offer(max.poll());	//将大顶堆中最大值加入小顶堆
            }else {	//当数据流为偶数时
                min.offer(num);	//加入小顶堆
                max.offer(min.poll());	//将小顶堆中最小值加入大顶堆
            }
        }

        public Double GetMedian() {
            if(count%2 == 0){	//当数据流为偶数时
                return (min.peek() + max.peek()) / 2.0;	//小顶堆最小值与大顶堆最大值的平均值
            }else{	//当数据流为奇数时
                return (double)min.peek();	//小顶堆的最小值
            }
        }
    }

二、思路二

使用List集合暴力解决

    public class Solution {
        ArrayList<Integer> list = new ArrayList<>();
        public void Insert(Integer num) {
            list.add(num);
            Collections.sort(list);
        }

        public Double GetMedian() {
            int n = list.size();
            if (n % 2 == 0)
                return Double.valueOf((list.get(n / 2) + list.get(n / 2 - 1)) / 2.0);
            else
                return Double.valueOf(list.get(n / 2));
        }
    }

以上是关于剑指offer:数据流中的中位数的主要内容,如果未能解决你的问题,请参考以下文章

剑指 Offer 41 数据流中的中位数(优先队列堆排序)

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

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

《剑指offer》:[64]数据流中的中位数

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

剑指offer数据流中的中位数