ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Continuous Median

2021-06-10 07:01:40  阅读:285  来源: 互联网

标签:self Continuous Median length currentIdx heap array def


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]
        

 

标签:self,Continuous,Median,length,currentIdx,heap,array,def
来源: https://www.cnblogs.com/LilyLiya/p/14869578.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有