zoukankan      html  css  js  c++  java
  • 数据流中的中位数

    题目描述:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
    如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

    解法一:

    public class Median {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Median p = new Median();
            p.Insert(4);
            p.Insert(3);
            p.Insert(6);
            p.Insert(5);
            System.out.println(p.GetMedian());
        }
    
        List<Integer> t=new LinkedList<Integer>();//定义一个LinkedList,可以知道插入的顺序
        public void Insert(Integer num) {//该插入函数是将数值判断以后再插入,得到的数列是已经排序好的
            if (t.isEmpty()) t.add(num);//如果t为空,则不用判断直接插入
            else if (num<t.get(0)) t.add(0,num);//如果小于第一个数值,则插入到最前面
            else if (num>t.get(t.size()-1)) t.add(num);//如果大于最后一个数值,在直接插入(在最后)
            else 
                for (int i = 0; i < t.size(); i++) {//否则,是大于第一个值,小于最后值,插入的位置需要判断
                    if (num>t.get(i)&&num<=t.get(i+1)){
                    t.add(i+1,num);
                    break;
                }
            }
             
        }
     
        public Double GetMedian() {
            int mid=t.size()/2;
            if (t.size()%2==1) return Double.valueOf(t.get(mid));
            else return (t.get(mid) + t.get(mid - 1)) / 2.0;
        }
     
    
    }

    解法二:

    用Java中自带的工具类处理,更方便

    public class Solution {
        ArrayList<Integer> list=new ArrayList<Integer>();
        public void Insert(Integer num) {
         list.add(num);
        }
    
        public Double GetMedian() {
            Collections.sort(list);//java自带的工具类可以实现排序
            int n=list.size();
            Double res=0.0;
            if(n%2==1){
               res= (Double)(list.get((n-1)/2)/2.0)*2.0;
            }
            if(n%2==0){
                res= (Double)((list.get(n/2-1)+list.get(n/2))/2.0);
            }
            return res;
        }
    }

    解法三:是从别人的代码中看到的,采用的是堆思想:

    //解题思路就是用两个堆,一个大顶堆,一个小顶堆来过滤数据。
    /**
    * 插入有两种思路:
    * 1:直接插入大堆中,之后若两堆尺寸之差大于1(也就是2),则从大堆中弹出堆顶元素并插入到小堆中
    * 若两队之差不大于1,则直接插入大堆中即可。
    * 2:奇数个数插入到大堆中,偶数个数插入到小堆中,
    * 但是 可能会出现当前待插入的数比小堆堆顶元素大,此时需要将元素先插入到小堆,然后将小堆堆顶元素弹出并插入到大堆中
    * 对于偶数时插入小堆的情况,一样的道理。why?
    * 因为要保证最大堆的元素要比最小堆的元素都要小。
    * @param num
    */

    public void Insert(Integer num) {
        //若总尺寸为偶数,则插入大顶堆中
        if(((maxHeap.si敏感词Heap.size()) & 1) == 0){
            if(minHeap.size() != 0 && num > minHeap.peek()){
                minHeap.add(num);
                maxHeap.add(minHeap.pop());
            }else{
                maxHeap.add(num);
            }
        }else{
            if(maxHeap.size() != 0 && num < maxHeap.peek()){
                maxHeap.add(num);
                minHeap.add(maxHeap.pop());
            }else{
                minHeap.add(num);
            }
        }
    }
    public Double GetMedian() {
        double res = 0.0;
        if(((maxHeap.si敏感词Heap.size()) & 1) == 0){
            res = (maxHeap.peek() + minHeap.peek()) / 2.0;
        }else{
            res = maxHeap.peek();
        }
        return res;
    }
    }

    //堆类,可直接设置最大堆最小堆

    class Heap {
        public List<Integer> list = null;
        public static final boolean isMaxHeap = true;
        public static final boolean isMinHeap = false;
        private boolean flag = true;  //true表示最大堆,false表示最小堆
        public Heap(){
            this.list = new ArrayList<Integer>();
        }
        public Heap(boolean flag){
            this.list = new ArrayList<Integer>();
            this.flag = flag;
        }
        //获取堆大小
        public int size(){
            return this.list.size();
        }
        //获取堆顶元素
        public int peek(){
            if(list.size() == 0) return 0;
            return list.get(0);
        }
        //插入元素,从插入点开始向上调整堆
        public void add(int val){
            this.list.add(val);
            int i = list.size() - 1, index, parent, cur;
            while(i > 0){
                index = (i - 1) / 2;
                parent = list.get(index);
                cur = list.get(i);
                if(flag == true && parent < cur){
                    swap(index, i);
                }else if(flag == false && parent > cur){
                    swap(index, i);
                }
                i = index;
            }
        }
        /**
         * 将堆顶元素取出,并重新调整堆。
         * 1>取出堆顶元素
         * 2>将最后一个元素放到堆顶
         * 3>向下调整堆
         
        public int pop(){
            if(list.size() == 0) return -1;
            int res = list.get(0);
            list.set(0,list.get(list.size() - 1));
            list.remove(list.size()-1);
            int len = list.size() - 1 , i = 0;
            int left , right;
            while(i < len){
                left = (i << 1) + 1;
                right= (i << 1) + 2;
                int maxIndex = i;
                if(flag == true){
                    if(left < len && list.get(left) > list.get(maxIndex)) maxIndex = left;
                    if(right< len && list.get(right)> list.get(maxIndex)) maxIndex = right;
                }else{
                    if(left < len && list.get(left) < list.get(maxIndex)) maxIndex = left;
                    if(right< len && list.get(right)< list.get(maxIndex)) maxIndex = right;
                }
                if(maxIndex != i){
                    swap(maxIndex,i);
                    i = maxIndex;
                }else break;
            }
            return res;
        }
        //交换list中两个位置的元素
        public void swap(int i, int j){
            int temp = list.get(i);
            list.set(i, list.get(j));
            list.set(j,temp);
        }
    }
  • 相关阅读:
    Golang Failpoint 的设计与实现
    没涉及到最值求解;观点:矩阵乘法无法表达出结果。 现实生活中事件、现象的数学表达
    多元微分学 枚举破解15位路由器密码 存储空间限制 拆分减长,求最值 数据去重
    ARP Poisoning Attack and Mitigation Techniques ARP欺骗 中间人攻击 Man-In-The-Middle (MITM) attack 嗅探 防范 Can one MAC address have two different IP addresses within the network?
    The C10K problem
    HTTP Streaming Architecture HLS 直播点播 HTTP流架构
    现代IM系统中消息推送和存储架构的实现
    现代IM系统中的消息系统架构
    长连接锁服务优化实践 C10K问题 nodejs的内部构造 limits.conf文件修改 sysctl.conf文件修改
    doubleclick cookie、动态脚本、用户画像、用户行为分析和海量数据存取 推荐词 京东 电商 信息上传 黑洞 https://blackhole.m.jd.com/getinfo
  • 原文地址:https://www.cnblogs.com/tjuxqcui/p/5541877.html
Copyright © 2011-2022 走看看