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]
            
  • 相关阅读:
    linux异常文件下载
    spring boot项目发布到tomcat端口问题
    jenkins.service changed on disk. Run 'systemctl daemon-reload' to reload units
    Job for jenkins.service failed because the control process exited with error code
    安装配置jenkins rpm方式
    Error creating bean with name 'eurekaAutoServiceRegistration': Singleton bean creation not allowed w
    Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of these environ
    Cannot find class: org.mybatis.caches.ehcache.LoggingEhcache
    java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
    Error:(12, 8) java: 无法访问javax.servlet.ServletException 找不到javax.servlet.ServletException的类文件
  • 原文地址:https://www.cnblogs.com/LilyLiya/p/14869578.html
Copyright © 2011-2022 走看看