标签: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. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。