Simple Solution with Diagrams in Video - JavaScript, C++, Java, Python
Video\nPlease upvote here so others save time too!\n\nLike the video on YouTube if you found it useful\n\nClick here to subscribe on YouTube:\nhttps://www.youtu
# Video\nPlease upvote here so others save time too!\n\nLike the video on YouTube if you found it useful\n\nClick here to subscribe on YouTube:\nhttps://www.youtube.com/@mayowadan?sub_confirmation=1\n\nThanks!\n\nhttps://youtu.be/bvWdhqlKIYQ?si=11EpRTbh-UHzr1mZ\n\n```Javascript []\nclass MinHeap {\n  constructor() {\n    this.heap = [];\n  }\n\n  size() {\n    return this.heap.length;\n  }\n\n  peek() {\n    return this.heap[0];\n  }\n\n  offer(value) {\n    this.heap.push(value);\n    this.bubbleUp();\n  }\n\n  poll() {\n    if (this.size() === 1) return this.heap.pop();\n    const root = this.heap[0];\n    this.heap[0] = this.heap.pop();\n    this.bubbleDown();\n    return root;\n  }\n\n  bubbleUp() {\n    let index = this.size() - 1;\n    const element = this.heap[index];\n    while (index > 0) {\n      const parentIndex = Math.floor((index - 1) / 2);\n      const parent = this.heap[parentIndex];\n      if (element >= parent) break;\n      this.heap[index] = parent;\n      index = parentIndex;\n    }\n    this.heap[index] = element;\n  }\n\n  bubbleDown() {\n    let index = 0;\n    const length = this.size();\n    const element = this.heap[0];\n    while (true) {\n      let leftChildIndex = 2 * index + 1;\n      let rightChildIndex = 2 * index + 2;\n      let leftChild, rightChild;\n      let swap = null;\n\n      if (leftChildIndex < length) {\n        leftChild = this.heap[leftChildIndex];\n        if (leftChild < element) {\n          swap = leftChildIndex;\n        }\n      }\n      if (rightChildIndex < length) {\n        rightChild = this.heap[rightChildIndex];\n        if (\n          (swap === null && rightChild < element) ||\n          (swap !== null && rightChild < leftChild)\n        ) {\n          swap = rightChildIndex;\n        }\n      }\n\n      if (swap === null) break;\n      this.heap[index] = this.heap[swap];\n      index = swap;\n    }\n    this.heap[index] = element;\n  }\n}\n\nvar MedianFinder = function() {\n    this.maxHeapForSmallNum = new MinHeap();\n    this.minHeapForLargeNum = new MinHeap();\n};\n\n/** \n * @param {number} num\n * @return {void}\n */\nMedianFinder.prototype.addNum = function(num) {\n    if (this.maxHeapForSmallNum.size() === 0 || -1 * this.maxHeapForSmallNum.peek() >= num) {\n        this.maxHeapForSmallNum.offer(-1 * num);\n    } else {\n        this.minHeapForLargeNum.offer(num);\n    }\n\n    if (this.maxHeapForSmallNum.size() > this.minHeapForLargeNum.size() + 1) {\n        this.minHeapForLargeNum.offer(-1 * this.maxHeapForSmallNum.poll());\n    } else if (this.maxHeapForSmallNum.size() < this.minHeapForLargeNum.size()) {\n        this.maxHeapForSmallNum.offer(-1 * this.minHeapForLargeNum.poll());\n    }\n};\n\n/**\n * @return {number}\n */\nMedianFinder.prototype.findMedian = function() {\n    if (this.maxHeapForSmallNum.size() === this.minHeapForLargeNum.size()) {\n        return (-1 * this.maxHeapForSmallNum.peek()) / 2.0 + this.minHeapForLargeNum.peek() / 2.0;\n    }\n    return -1 * (this.maxHeapForSmallNum.peek() / 1.0);\n};\n\n/** \n * Your MedianFinder object will be instantiated and called as such:\n * var obj = new MedianFinder()\n * obj.addNum(num)\n * var param_2 = obj.findMedian()\n */\n\n```\n```Python []\nclass MedianFinder:\n\n    def __init__(self):\n        # Min-heap for the larger half of the numbers\n        self.minHeapForLargeNum = []\n        # Max-heap for the smaller half of the numbers (invert numbers to use\n        # heapq as a max-heap)\n        self.maxHeapForSmallNum = []\n\n    def addNum(self, num: int) -> None:\n        if len(self.maxHeapForSmallNum) == 0 or -self.maxHeapForSmallNum[0] >= num:\n            heapq.heappush(self.maxHeapForSmallNum, -num)\n        else:\n            heapq.heappush(self.minHeapForLargeNum, num)\n\n        # Balance the heaps\n        if len(self.maxHeapForSmallNum) > len(self.minHeapForLargeNum) + 1:\n            heapq.heappush(\n                self.minHeapForLargeNum, -heapq.heappop(self.maxHeapForSmallNum)\n            )\n        elif len(self.maxHeapForSmallNum) < len(self.minHeapForLargeNum):\n            heapq.heappush(\n                self.maxHeapForSmallNum, -heapq.heappop(self.minHeapForLargeNum)\n            )\n\n    def findMedian(self) -> float:\n        if len(self.maxHeapForSmallNum) == len(self.minHeapForLargeNum):\n            return (-self.maxHeapForSmallNum[0] + self.minHeapForLargeNum[0]) / 2.0\n        else:\n            return -self.maxHeapForSmallNum[0]\n\n\n# Your MedianFinder object will be instantiated and called as such:\n# obj = MedianFinder()\n# obj.addNum(num)\n# param_2 = obj.findMedian()\n\n```\n```Java []\nclass MedianFinder {\n\n    // Min-heap for the larger half of the numbers\n    private PriorityQueue<Integer> minHeapForLargeNum;\n    // Max-heap for the smaller half of the numbers\n    private PriorityQueue<Integer> maxHeapForSmallNum;\n\n    public MedianFinder() {\n        // Initializing the heaps\n        minHeapForLargeNum = new PriorityQueue<>();\n        maxHeapForSmallNum = new PriorityQueue<>((a, b) -> b - a);\n    }\n    \n    public void addNum(int num) {\n        if (maxHeapForSmallNum.isEmpty() || maxHeapForSmallNum.peek() >= num) {\n            maxHeapForSmallNum.offer(num);\n        } else {\n            minHeapForLargeNum.offer(num);\n        }\n        \n        // Balance the heaps\n        if (maxHeapForSmallNum.size() > minHeapForLargeNum.size() + 1) {\n            minHeapForLargeNum.offer(maxHeapForSmallNum.poll());\n        } else if (maxHeapForSmallNum.size() < minHeapForLargeNum.size()) {\n            maxHeapForSmallNum.offer(minHeapForLargeNum.poll());\n        }\n    }\n    \n    public double findMedian() {\n        if (maxHeapForSmallNum.size() == minHeapForLargeNum.size()) {\n            return (maxHeapForSmallNum.peek() / 2.0) + (minHeapForLargeNum.peek() / 2.0);\n        } else {\n            return maxHeapForSmallNum.peek();\n        }\n    }\n}\n\n/**\n * Your MedianFinder object will be instantiated and called as such:\n * MedianFinder obj = new MedianFinder();\n * obj.addNum(num);\n * double param_2 = obj.findMedian();\n */\n```\n```C++ []\nclass MedianFinder {\npublic:\n    // Min-heap for the larger half of the numbers\n    priority_queue<int, std::vector<int>, std::greater<int>> minHeapForLargeNum;\n    // Max-heap for the smaller half of the numbers\n    priority_queue<int> maxHeapForSmallNum;\n\n    MedianFinder() {\n        // No need for explicit initialization as the heaps are already\n        // initialized\n    }\n\n    void addNum(int num) {\n        if (maxHeapForSmallNum.empty() || maxHeapForSmallNum.top() >= num) {\n            maxHeapForSmallNum.push(num);\n        } else {\n            minHeapForLargeNum.push(num);\n        }\n\n        // Balance the heaps\n        if (maxHeapForSmallNum.size() > minHeapForLargeNum.size() + 1) {\n            minHeapForLargeNum.push(maxHeapForSmallNum.top());\n            maxHeapForSmallNum.pop();\n        } else if (maxHeapForSmallNum.size() < minHeapForLargeNum.size()) {\n            maxHeapForSmallNum.push(minHeapForLargeNum.top());\n            minHeapForLargeNum.pop();\n        }\n    }\n\n    double findMedian() {\n        if (maxHeapForSmallNum.size() == minHeapForLargeNum.size()) {\n            return (maxHeapForSmallNum.top() / 2.0) +\n                   (minHeapForLargeNum.top() / 2.0);\n        } else {\n            return maxHeapForSmallNum.top();\n        }\n    }\n};\n\n/**\n * Your MedianFinder object will be instantiated and called as such:\n * MedianFinder* obj = new MedianFinder();\n * obj->addNum(num);\n * double param_2 = obj->findMedian();\n */\n\n```\n\n
['Python', 'C++', 'Java', 'Python3', 'JavaScript']