From 9e05565d36b4e8708ec891dbfca5c1f4597d68bd Mon Sep 17 00:00:00 2001 From: Manish Date: Thu, 9 Mar 2023 23:33:52 +1100 Subject: [PATCH] Design Pattern 10: Two Heaps: Problem: Find Median from Data Stream --- 10_find_the_median_of_a_number_stream.cpp | 82 +++++++++++++++++++++++ CMakeLists.txt | 2 + 2 files changed, 84 insertions(+) create mode 100644 10_find_the_median_of_a_number_stream.cpp diff --git a/10_find_the_median_of_a_number_stream.cpp b/10_find_the_median_of_a_number_stream.cpp new file mode 100644 index 0000000..9181ab8 --- /dev/null +++ b/10_find_the_median_of_a_number_stream.cpp @@ -0,0 +1,82 @@ +/* Problem: https://leetcode.com/problems/find-median-from-data-stream/ + */ + +#include +#include +#include +#include +#include +#include + +enum class action { addNum, findMedian }; + +struct instruction { + action do_; + double val; +}; +class MedianFinder { +private: + std::priority_queue, std::greater> + min_heap{std::greater{}, {std::numeric_limits::max()}}; + std::priority_queue max_heap{std::less{}, + {std::numeric_limits::lowest()}}; + +public: + MedianFinder() {} + + void addNum(double num) { + if (min_heap.size() == max_heap.size()) { + if (num > min_heap.top()) { + min_heap.push(num); + } else { + max_heap.push(num); + } + } else if (min_heap.size() < max_heap.size()) { + if (num > max_heap.top()) { + min_heap.push(num); + } else { + min_heap.push(max_heap.top()); + max_heap.pop(); + max_heap.push(num); + } + } else { + if (num > min_heap.top()) { + max_heap.push(min_heap.top()); + min_heap.pop(); + min_heap.push(num); + } else { + max_heap.push(num); + } + } + } + + double findMedian() { + if (min_heap.size() == max_heap.size()) { + return (min_heap.top() + max_heap.top()) / 2; + } else if (min_heap.size() < max_heap.size()) { + return max_heap.top(); + } else { + return min_heap.top(); + } + } +}; + +int main() { + std::vector instructions = {{action::addNum, 1}, + {action::addNum, 2}, + {action::findMedian, 0}, + {action::addNum, 3}, + {action::findMedian, 0}}; + MedianFinder *median_finder = new MedianFinder(); + std::cout << "{"; + for (instruction &i : instructions) { + if (i.do_ == action::addNum) { + median_finder->addNum(i.val); + std::cout << "null, "; + } else if (i.do_ == action::findMedian) { + i.val = median_finder->findMedian(); + std::cout << i.val << ", "; + } + } + std::cout << "\b\b}\n"; +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 257b91a..3c1b9b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,3 +22,5 @@ add_executable(7_reverse_nodes_in_k_group 7_reverse_nodes_in_k_group.cpp) add_executable(8_binary_tree_level_order_traversal 8_binary_tree_level_order_traversal.cpp) add_executable(9_path_sum_iii 9_path_sum_iii.cpp) + +add_executable(10_find_the_median_of_a_number_stream 10_find_the_median_of_a_number_stream.cpp)