zoukankan      html  css  js  c++  java
  • Continuous Median

    refer to: https://www.algoexpert.io/questions/Continuous%20Median


    Problem statement

    Analysis

    O(N) for insert one number into a sorted array

    Code

    def MAX_HEAP_FUNC(a, b):
            return a > b
        
    def MIN_HEAP_FUNC(a, b):
            return a < b
    
    class ContinuousMedianHandler:
        def __init__(self):
            self.lowers = Heap(MAX_HEAP_FUNC, []) #create a maxheap for lower half of the numbers
            self.greaters = Heap(MIN_HEAP_FUNC, []) #create a minheap for greater half of the numbers
            self.median = None
    
        def insert(self, number): 
            if not self.lowers.length or number < self.lowers.peek():#empty lower heap or the new number < the peek of the lower maxheap
                self.lowers.insert(number)
            else:
                self.greaters.insert(number)
            self.rebalanceHeaps() # balance the lower and greater heaps, make sure the different between their lengths <= 1
            self.updateMedian() #update new median value
            
        def rebalanceHeaps(self):
            if self.lowers.length - self.greaters.length == 2: # lower heap has more values
                self.greater.insert(self.lowers.remove())# remove the peek(max value) of the lower heap into the greater heap
            elif self.greaters.length - self.lowers.length == 2:
                self.lowers.insert(self.greaters.remove())
        def updateMedian(self): 
            if self.lowers.length == self.greaters.length: # same length, the two mid values are peeks of low and great heaps
                self.median = (self.lowers.peek() + self.greaters.peek())/2
            elif self.lowers.length > self.greaters.length: # lower heap has more one valye, the peek one of lower heap
                self.median = self.lowers.peek()
            else: # higher heap has more one value
                self.median = self.greaters.peek()
        def getMedian(self):
            return self.median

    Time and space complexity

    time: log(n) time for insert, remove in heaps.

    space: store all the numbers in heap->O(N)

    The Heap class

    class Heap:
        def __init__(self, comparisonFunc, array):
            self.comparisonFunc = comparisonFunc
            self.heap = self.buildHeap(array)
            self.length = len(self.heap)
        def buildHeap(self, array):
            firstParentIdx = (len(array) - 2) //2
            for currentIdx in reversed(range(firstParentIdx + 1)):
                self.siftDown(currentIdx, len(array) - 1, array)
            return array
        def siftDown(self, currentIdx, endIdx, heap):
            childOneIdx = currentIdx *2 + 1
            while childOneIdx <= endIdx:
                childTwoIdx = currentIdx * 2 + 2 if currentIdx * 2 + 2 <= endIdx else - 1
                if childTwoIdx != -1:
                    if self.comparisonFunc(heap[childTwoIdx], heap[childOneIdx]):
                        idxToSwap = childTwoIdx
                    else:
                        idxToSwap = childOneIdx
                else:
                    idxToSwap = childOneIdx
                if self.comparisonFunc(heap[idxToSwap], heap[currentIdx]):
                    self.swap(currentIdx, idxToSwap, heap)
                    currentIdx = idxToSwap
                    childOneIdx = currentIdx * 2 + 1
                else:
                    return
        
        def siftUp(self, currentIdx, heap):
            parentIdx = (currentIdx - 1) // 2
            while currentIdx > 0:
                if self.comparisonFunc(heap[currentIdx], heap[parentIdx]):
                    self.swap(currentIdx, parentIdx, heap)
                    currentIdx = parentIdx
                    parentIdx = (currentIdx - 1) // 2
                else:
                    return
        
        def peek(self):
            return self.heap[0]
    
        
        def remove(self):
            self.swap(0, self.length - 1, self.heap)
            valueToRemove = self.heap.pop()
            self.length -= 1
            self.siftDown(0, self.length - 1, self.heap)
            return valueToRemove
        
        def insert(self, value):
            self.heap.append(value)
            self.length += 1
            self.siftUp(self.length - 1, self.heap)
            
        def swap(self, i, j, array):
            array[i],array[j] = array[j], array[i]
            
  • 相关阅读:
    Oozie_02安装遇到错误【20161116】
    Oozie_01安装教程【20161116】
    hadoop2.x常用端口及定义方法
    谷歌浏览器怎么调试js 谷歌浏览器调试javascript教程
    找回密码(一)【实际项目】
    解决使用SecureCRT出现的Generic clipboard failure错误【自己亲身经历】
    [php]php总结(2)
    [php]php总结(1)
    [php]php时间格式化
    [hadoop]mapreduce原理简述
  • 原文地址:https://www.cnblogs.com/LilyLiya/p/14869578.html
Copyright © 2011-2022 走看看