Problem description:
Returns a random string of I, which must be the number in the middle of the size.
Algorithm Description:
In general, insert sorting is performed, and the median value is at half of the index. The time complexity is average. Insert the average time complexity of sorting O (n2) and find the intermediate time.
Value, the efficiency is not high.
The practice here is to introduce the data structure-Heap to solve the problem. The time complexity is O (logn ).
Two heaps, max heap and min heap, are introduced to store the two parts of the integer string I. The following conditions must be met:
1. Size Condition
The number of elements in max heap can be equal to or greater than that in min. Otherwise, adjust the value.
2. Order Conditions
Max heap stores small values in the first half
Min heap stores large values in the second half.
The maximum value in max heap can only be smaller or equal than the minimum value in min. Otherwise, adjust the value.
That is, the average value of the heap top value generated by median in max heap, or in max heap and min heap.
The Code is as follows:
class MyHeap: # heap type MAX_HEAP = 1 MIN_HEAP = 0 def __init__(self, type=MAX_HEAP, arr=None): self.type = type # if init directly by array if arr is not None: self.data = arr[:] length = len(arr) # the last non leave node begin = length / 2 - 1 for i in range(begin, -1, -1): self.heapify(i) else: self.data = [] def __heapify(self, i): length = len(self.data) left = self.__leftChild(i) right = self.__rightChild(i) largest = i while left < length or right < length: if self.type == self.MAX_HEAP: if left < length and self.data[left] > self.data[largest]: largest = left if right < length and self.data[right] > self.data[largest]: largest = right elif self.type == self.MIN_HEAP: if left < length and self.data[left] < self.data[largest]: largest = left if right < length and self.data[right] < self.data[largest]: largest = right if i != largest: self.__swap(i, largest) i = largest left = self.__leftChild(i) right = self.__rightChild(i) else: break def inset(self, item): self.data.insert(0, item) # heapify starts from 0 self.__heapify(0) def delete(self, index): self.data.pop(index) # if delete the 0 index item, heapify from 0 self.heapify(index - 1 if index - 1 else 0) def pop(self): # pop the extreme value, what ever it is max or min self.__swap(0, len(self.data) - 1) extreme = self.data.pop() self.__heapify(0) return extreme # overwrite the getitem method of MyHeap class, # so you can use [] to get value by index def __getitem__(self, index): if len(self.data) == 0: raise Error("no items") return self.data[index] # overwrite the len method of MyHeap class, # so you can len(heapclass) to get the size of heap def __len__(self): return len(self.data) def __swap(self, i, j): temp = self.data[i] self.data[i] = self.data[j] self.data[j] = temp # index of array starts from zero def __rightChild(self, i): return 2 * i + 1 def __leftChild(self, i): return 2 * i + 2 # overwrite the repr method of MyHeap class, # so you can print the readability info of heap def __repr__(self): return str(self.data) class MedianMaintain: def __init__(self): self.maxHeap = MyHeap(MyHeap.MAX_HEAP) self.minHeap = MyHeap(MyHeap.MIN_HEAP) # the total number of items in both heaps self.N = 0 def insert(self, item): # to obey size requirement rule, before insertion, if # total number is even, it is OK, insert new item to # max heap, and then adjust it if self.N % 2 == 0: self.maxHeap.inset(item) self.N += 1 if len(self.minHeap) == 0: return # to obey order requirement rule, largest of items in max heap should # less or equal than smallest of the items in the min heap, if not, # swap them if self.maxHeap[0] > self.minHeap[0]: toMin = self.maxHeap.pop() toMax = self.minHeap.pop() self.maxHeap.inset(toMax) self.minHeap.inset(toMin) else: # to obey the size requirement rule, before insertion, if the size of # max heap is odd, then to insert the new item, and pop the extreme value # to insert into min heap self.maxHeap.inset(item) toMin = self.maxHeap.pop() self.minHeap.inset(toMin) self.N += 1 def getMedian(self): # if total size if even, the median is the average of value of root of min and max heap if self.N % 2 == 0: return (self.maxHeap[0] + self.minHeap[0]) / 2.0 else: # if total size if odd, median is root of max heap return self.maxHeap[0] def __repr__(self): return "max heap: " + str(self.maxHeap) + '\n' + "min heap: " + str(self.minHeap) if __name__ == "__main__": medianMaintain = MedianMaintain() medianMaintain.insert(5) medianMaintain.insert(4) medianMaintain.insert(3) medianMaintain.insert(2) medianMaintain.insert(1) medianMaintain.insert(6) print medianMaintain print medianMaintain.getMedian()