Leetcode Note: Find Median from Data Stream
I. Description
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 is3
[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:
add(1)add(2)findMedian() -> 1.5add(3) findMedian() -> 2
Ii. Question Analysis
The question is to find the median in a string of input data streams. Median refers to the median value of the ordered integer list. If the length of the list is an even number, there is no median. The number of digits is the average of the two median values.
For example:
[2,3,4], Median is3
[2,3], Median is(2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
Void addNum (int num) // This function adds an integer from the data flow data structure
Double findMedian () // returns the median of all elements as of now
The classic practice of this question is to maintain a maximum heap and a minimum heap. The largest Heap Storage is the half of the smaller ones so far, and the smallest Heap Storage is the half of the larger ones so far, in this way, the median value can only be the average value of the two numbers corresponding to the heap top or the two heap top.
The trick to maintain the two heaps is to judge the size Relationship Between the number at the top of the heap and the number of new inserts. In addition, because the two heaps share all the values, we also need to consider the size relationship between the two. Here we stipulate that the difference between the two heaps cannot exceed1. First, determine the relationship between the heap number and the new number. There are three situations:
When the minimum heap top is smaller than the number of new inserts, it indicates that the number of new inserts is in the upper half of all; when the maximum heap top is larger than the number of new inserts, it indicates that the number of new inserts is in the lower half of all; when the minimum heap top is larger than the number of new inserts, but the maximum heap top is smaller than the number of new inserts, it indicates that the number of new Inserts will be at the minimum heap top or the maximum heap top, that is, in the middle.
Then judge the size relationship between the two heaps. If the number of newly inserted items belongs to the first two cases, insert the target heap. At this time, there are two operations:
If the target heap is not larger than the other heap, insert a new number into the target heap. If the target heap is larger than the other, move the heap of the target heap to the other, insert the new number into the target heap.
If the number of new inserts is in the middle of the third case, insert it to the heap with a small size. In this way, after a new number is added each time, if the two heaps are the same size, the median is the average value of the two heaps. OtherwiseThe heap top of the larger heapIs the median.
The code used to create two heaps is relatively long, while the implementation of priority queue is much simpler.
Priority_queue: a priority queue, which is a one-way queue with an ownership value. In this queue, all elements are sorted by priority. There are two types of priority queues, one is the maximum priority queue; the other is the minimum priority queue; the first element retrieved from the queue each time is the highest priority and the smallest priority element.
In actual use, add the header file:"queue.h","functional.h"
"Functional. h" defines the priority. (If you want to customize the priority, you can leave it empty)
Iii. Sample Code
Class MedianFinder {private: priority_queue
, Std: greater
> Q1; // The smaller the data, the higher the priority, priority_queue
Q2; // higher data, higher priority public: void addNum (int num) {if (q2.empty () {q2.push (num); return ;} if (num <= q2.top () {if (q2.size () <= q1.size () q2.push (num); else {q1.push (q2.top (); q2.pop (); q2.push (num) ;}} else {if (q2.size () <= q1.size () {if (num <= q1.top () q2.push (num ); else {q2.push (q1.top (); q1.pop (); q1.push (num) ;}} else {q1.push (num) ;}} double findMedian () {if (q1.size () = q2.size () return (q1.top () + q2.top ()/2.0; return double (q2.top ());}}; // Your MedianFinder object will be instantiated and called as such: // MedianFinder mf; // mf. addNum (1); // mf. findMedian ();
Iv. Summary
I learned the queue first and benefited a lot.