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

    剑指OFFER_数据流中的中位数

    题目描述

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

    思路

    我觉得刷题的思路应该是从无到有,然后再从有到更好;

    秉持着这样的思路,先从最简单的思路解这道题,按照题意先做一个容器容纳这个数据流;

    然后对这个容器排序,并记录容器长度;

    输出结果时,如果长度为奇数,则输出中位数,为偶数则求均值;

    优化的思路就是就是sort函数,倒不是说sort函数不好用,而是其实vector中其实本来就排好顺序的,只是增加一个,所以只需要插入一个数到这个有序的容器中就好了,很自然的就想到了二分法;

    好吧其实完成后也没提高多少,从5ms提升到了3ms,代码如下:

    代码_暴力

    class Solution {
    public:
        int len = 0;
        vector<int> S;
        void Insert(int num)
        {
            ++len;
            S.push_back(num);
            
            // 待优化
            sort(S.begin(), S.end());
        }
    
        double GetMedian()
        { 
            if (len % 2 == 1) {
                return (double)S[len/2];
            }else {
                return (double)(S[len/2]+S[len/2-1])/2;
            }
        }
    
    };
    

    代码_二分法

    class Solution {
    public:
        int len = 0;
        vector<int> S;
        
        void dichotomy(int begin, int end, const int& num) {
            if (end - begin <= 1) {
                if (num < S[begin]) {
                    S.insert(S.begin()+begin, num);
                }else if (num > S[end]) {
                    S.insert(S.begin()+end+1, num);
                }else{
                    S.insert(S.begin()+end, num);
                }
                return;
            }
        	int mid = (begin + end)/2;
        	if (S[mid] > num) {
        		dichotomy(begin, mid, num);
        	} else {
        		dichotomy(mid, end, num);
        	}
        }
        void Insert(int num)
        {
            if (len == 0) {
            	S.push_back(num);
            }else {
            	dichotomy(0, len-1, num);
            }
         	++len;  
        }
    
        double GetMedian()
        { 
            if (len % 2 == 1) {
                return (double)S[len/2];
            }else {
                return (double)(S[len/2]+S[len/2-1])/2;
            }
        }
    
    };
    
  • 相关阅读:
    Django数据库查询优化-事务-图书管理系统的搭建
    模型层字段-多表查询-神奇的双下划线查询-F,Q查询
    Django的View(视图)-settings源码的解析-模板层-模板语法
    Django路由层与视图层
    Django框架的前奏(安装及介绍)
    面向对象的三大特性
    一,类的初识
    一,对象初识
    装饰器
    闭包
  • 原文地址:https://www.cnblogs.com/sakurapiggy/p/13194917.html
Copyright © 2011-2022 走看看