zoukankan      html  css  js  c++  java
  • [算法]返回中位数

    题目

    设计一个数据结构,使其能够在接收一个数据流时(数据流全部为整数),动态的返回已经接收到数据的中位数

    思路

    设计一个大顶堆B,一个小顶堆S,第一个数使其进入B,然后把这个数作为比较的对象,大于这个数使其进入S,小于这个数进入B,每一次进入操作后,执行调整操作,如果两个堆的size之差大于2,进行调整,pop堆顶元素进入另一个堆,这个思路有点像AVL树的思路

    实现

    package MyExc;
    
    import java.util.Comparator;
    import java.util.PriorityQueue;
    
    //大根堆
    class MaxIntegerHeap implements Comparator<Integer>{
    
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2.compareTo(o1);
        }
    }
    
    
    public class MedianHolder {
        private PriorityQueue<Integer> heap1 = new PriorityQueue<>(new MaxIntegerHeap());
        private PriorityQueue<Integer> heap2 = new PriorityQueue<>(/*new MaxIntegerHeap()*/);
        private int com;
    
        public void push(int data){
            if(heap1.isEmpty()&&heap2.isEmpty()){
                heap1.add(data);
                com = data;
            }else{
                if(data<=com){
                    heap1.add(data);
                }else if(data>com){
                    heap2.add(data);
                }
            }
            adjust(heap1,heap2);
        }
    
        private void adjust(PriorityQueue<Integer> heap1, PriorityQueue<Integer> heap2) {
            if(heap1.size()-heap2.size()>1){
                heap2.add(heap1.poll());
            }else if(heap2.size()-heap1.size()>1){
                heap1.add(heap2.poll());
            }
        }
    
        public float getMedian(){
            if(heap1.size()==heap2.size()){
                return (float)(heap1.poll()+heap2.poll())/2;
            }else if(heap1.size()>heap2.size()){
                return heap1.poll();
            }else{
                return heap2.poll();
            }
        }
    }
    

    测试代码

    package MyExc;
    
    public class Test {
        @org.junit.Test
        public void run(){
            MedianHolder medianHolder = new MedianHolder();
            medianHolder.push(1);
            medianHolder.push(2);
            medianHolder.push(3);
            medianHolder.push(4);
            medianHolder.push(5);
            medianHolder.push(6);
            medianHolder.push(7);
            medianHolder.push(1000);
    
            System.out.println(medianHolder.getMedian());
        }
    }
    

    改良思路

    我目前使用的是第一个数始终作为比较的参照物,似乎动态调节比较合理,把B堆的堆顶作为比较的参照物比较合理

  • 相关阅读:
    angular项目中使用jquery的问题
    angular项目中使用Primeng
    angular项目中使用angular-material2
    angular中使用AMEXIO
    angular项目中使用ngSemantic
    LeetCode——无重复字符的最长子串
    LeetCode——实现 strStr()
    Java split函数
    Java JavaScript 输入输出
    Java Stack,Queue,PriorityQueue,deque相关操作
  • 原文地址:https://www.cnblogs.com/kristse/p/getMedian.html
Copyright © 2011-2022 走看看