[JavaScript] max-heap + min-heap
\n/**\n * initialize your data structure here.\n */\nvar MedianFinder = function() {\n    this.maxHeap = new Heap(Heap.maxComparator);\n    this.minHeap = new H
```\n/**\n * initialize your data structure here.\n */\nvar MedianFinder = function() {\n    this.maxHeap = new Heap(Heap.maxComparator);\n    this.minHeap = new Heap(Heap.minComparator);\n};\n\n/** \n * @param {number} num\n * @return {void}\n */\nMedianFinder.prototype.addNum = function(num) {\n    if(this.maxHeap.peek() === null || num < this.maxHeap.peek()) {\n        this.maxHeap.add(num);\n    } else {\n        this.minHeap.add(num);\n    }\n    \n    if(this.maxHeap.size - this.minHeap.size > 1) {\n        this.minHeap.add(this.maxHeap.poll());\n    } else if(this.minHeap.size - this.maxHeap.size > 1) {\n        this.maxHeap.add(this.minHeap.poll());\n    }\n};\n\n/**\n * @return {number}\n */\nMedianFinder.prototype.findMedian = function() {\n    if(this.maxHeap.size > this.minHeap.size) {\n        return this.maxHeap.peek();\n    } else if(this.maxHeap.size < this.minHeap.size) {\n        return this.minHeap.peek();\n    } else {\n        return (this.maxHeap.peek() + this.minHeap.peek()) / 2;\n    }\n};\n\n/** \n *  custom Heap class\n */\nclass Heap {\n\tconstructor(comparator) {\n\t\tthis.size = 0;\n\t\tthis.values = [];\n\t\tthis.comparator = comparator || Heap.minComparator;\n\t}\n\n\tadd(val) {\n\t\tthis.values.push(val);\n\t\tthis.size ++;\n\t\tthis.bubbleUp();\n\t}\n\n\tpeek() {\n\t\treturn this.values[0] || null;\n\t}\n\n\tpoll() {\n\t\tconst max = this.values[0];\n\t\tconst end = this.values.pop();\n\t\tthis.size --;\n\t\tif (this.values.length) {\n\t\t\tthis.values[0] = end;\n\t\t\tthis.bubbleDown();\n\t\t}\n\t\treturn max;\n\t}\n\n\tbubbleUp() {\n\t\tlet index = this.values.length - 1;\n\t\tlet parent = Math.floor((index - 1) / 2);\n\n\t\twhile (this.comparator(this.values[index], this.values[parent]) < 0) {\n\t\t\t[this.values[parent], this.values[index]] = [this.values[index], this.values[parent]];\n\t\t\tindex = parent;\n\t\t\tparent = Math.floor((index - 1) / 2);\n\t\t}\n\t}\n\n\tbubbleDown() {\n\t\tlet index = 0, length = this.values.length;\n\n\t\twhile (true) {\n\t\t\tlet left = null,\n\t\t\t\tright = null,\n\t\t\t\tswap = null,\n\t\t\t\tleftIndex = index * 2 + 1,\n\t\t\t\trightIndex = index * 2 + 2;\n\n\t\t\tif (leftIndex < length) {\n\t\t\t\tleft = this.values[leftIndex];\n\t\t\t\tif (this.comparator(left, this.values[index]) < 0) swap = leftIndex;\n\t\t\t}\n\n\t\t\tif (rightIndex < length) {\n\t\t\t\tright = this.values[rightIndex];\n\t\t\t\tif ((swap !== null && this.comparator(right, left) < 0) || (swap === null && this.comparator(right, this.values[index]))) {\n\t\t\t\t\tswap = rightIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (swap === null) break;\n\n\t\t\t[this.values[index], this.values[swap]] = [this.values[swap], this.values[index]];\n\t\t\tindex = swap;\n\t\t}\n\t}\n}\n\n/** \n *  Min Comparator\n */\nHeap.minComparator = (a, b) => { return a - b; }\n\n/** \n *  Max Comparator\n */\nHeap.maxComparator = (a, b) => { return b - a; }\n```
['Heap (Priority Queue)', 'JavaScript']