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

    数据流中的中位数

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

    思路:这道题用到两个堆,一定要保证前面的最大堆元素多于后面的最小堆元素,首先将元素压入最大堆,然后取出最小的元素压入最小堆,然后判断两者大小,最大堆数目小于最小堆,流需要压一个最小堆的元素到前面的最大堆。
    最后得结果的时候,是奇数返回前面最大堆的top,否则数目不为0的时候,返回两个堆的top平均数。
     
    import (
        "container/heap"
    )
    type Heap []int
    
    func (m *Heap)Swap(i,j int){
        (*m)[i],(*m)[j]=(*m)[j],(*m)[i]
    }
    
    func (m *Heap)Len()int{
        return len(*m)
    }
    
    func (m *Heap)Pop()(v interface{}){
        *m,v = (*m)[:len(*m)-1],(*m)[len(*m)-1]
        return
    }
    
    func (m *Heap)Push(v interface{}){
        *m = append(*m,v.(int))
    }
    
    type minHeap struct {
        Heap
    }
    
    func (m *minHeap)Less(i,j int)bool{
        return m.Heap[i] < m.Heap[j]
    }
    
    type maxHeap struct {
        Heap
    }
    
    func (m *maxHeap)Less(i,j int)bool{
        return m.Heap[i] > m.Heap[j]
    }
    
    
    type MedianFinder struct {
        RightMin *minHeap
        LeftMax  *maxHeap
    }
    
    
    /** initialize your data structure here. */
    func Constructor() MedianFinder {
        m := new(MedianFinder)
        m.RightMin = new(minHeap)
        m.LeftMax = new(maxHeap)
        heap.Init(m.LeftMax)
        heap.Init(m.RightMin)
        return *m
    }
    
    
    func (this *MedianFinder) AddNum(num int)  {
        // 压入数据时有两种情况;
        // (1)原有数据为偶数个,则有 leftheap.len() == rightheap.len();
        //     此时将数据放入leftheap, 高明之处:需先将数据放在rightheap,再从rightheap中pop出一个元素,将其放入leftheap;
        //     上面做法的高明之处 在于 省去了判断 num 与 rightheap最小值 及 leftheap最大值 的比较,通过比较判断num应该放在哪个heap,
        //     然后再根据左右heap的长度,对左右heap进行调整
        //  (2) 原有数据为奇数个,则有 leftheap.len() == rightheap.len() + 1  (通过step 1 来保证当为奇数时,left总比right 大 1,这样可以简化判断)
        //     类似step 1 需先将数据放在leftheap,再从leftheap中pop出一个元素,将其放入rightheap中
        if this.LeftMax.Len() == this.RightMin.Len(){
            heap.Push(this.RightMin,num)
            heap.Push(this.LeftMax,heap.Pop(this.RightMin))
        }else{
            heap.Push(this.LeftMax,num)
            heap.Push(this.RightMin,heap.Pop(this.LeftMax))
        }
    }
    
    
    func (this *MedianFinder) FindMedian() float64 {
        if (this.RightMin.Len()+this.LeftMax.Len())%2==0{
            //此处根据heap的实现原理,直接获取heap的第一个元素,即为大顶堆的最大值
            return float64(this.LeftMax.Heap[0]+this.RightMin.Heap[0])/2
        }else{
            return float64(this.LeftMax.Heap[0])
        }
    }
     
  • 相关阅读:
    Python多线程编程
    Python解析HTML的开发库pyquery
    Python标准库之urllib,urllib2自定义Opener
    Python标准库之urllib,urllib2
    Python中Cookie的处理(二)cookielib库
    Python中Cookie的处理(一)Cookie库
    Linux下删除大量文件
    部分Dojo常用函数简介(三)——页面生命周期及DOM相关常用函数
    Web流程
    如何理解JS项目
  • 原文地址:https://www.cnblogs.com/dingxiaoqiang/p/14642801.html
Copyright © 2011-2022 走看看