Problem:
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Examples:
[2,3,4]
, the median is 3
[2,3]
, the median is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
- void addNum(int num) – Add a integer number from the data stream to the data structure.
- double findMedian() – Return the median of all elements so far.
For example:
1 2 3 4 5 |
addNum(1) addNum(2) findMedian() = 1.5 addNum(3) findMedian() = 2 |
Idea:
- Min/Max heap
- Balanced binary search tree
Time Complexity:
add(num): O(logn)
findMedian(): O(logn)
Solution1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// Author: Huahua // Running Time: 152 ms class MedianFinder { public: /** initialize your data structure here. */ MedianFinder() {} // l_.size() >= r_.size() void addNum(int num) { if (l_.empty() || num <= l_.top()) { l_.push(num); } else { r_.push(num); } // Step 2: Balence left/right if (l_.size() < r_.size()) { l_.push(r_.top()); r_.pop(); } else if (l_.size() - r_.size() == 2) { r_.push(l_.top()); l_.pop(); } } double findMedian() { if (l_.size() > r_.size()) { return static_cast<double>(l_.top()); } else { return (static_cast<double>(l_.top()) + r_.top()) / 2; } } private: priority_queue<int, vector<int>, less<int>> l_; // max-heap priority_queue<int, vector<int>, greater<int>> r_; // min-heap }; |
Solution 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// Author: Huahua // Running time: 172 ms class MedianFinder { public: /** initialize your data structure here. */ MedianFinder(): l_(m_.cend()), r_(m_.cend()) {} // O(logn) void addNum(int num) { if (m_.empty()) { l_ = r_ = m_.insert(num); return; } m_.insert(num); const size_t n = m_.size(); if (n & 1) { // odd number if (num >= *r_) { l_ = r_; } else { // num < *r_, l_ could be invalidated l_ = --r_; } } else { if (num >= *r_) ++r_; else --l_; } } // O(1) double findMedian() { return (static_cast<double>(*l_) + *r_) / 2; } private: multiset<int> m_; multiset<int>::const_iterator l_; // current left median multiset<int>::const_iterator r_; // current right median }; |
Related Problems
请尊重作者的劳动成果,转载请注明出处!花花保留对文章/视频的所有权利。
如果您喜欢这篇文章/视频,欢迎您捐赠花花。
If you like my articles / videos, donations are welcome.
Be First to Comment