How to get the median in a data stream? If an odd number of values are read out from the data stream, the median is the value in the middle after all values are sorted. If an even number of values are read from the data stream, the median is the average of the middle two numbers after all values are sorted.
For example,
The median of [2,3,4] is 3
The median of [2,3] is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
void addNum(int num) - adds an integer from the data stream to the data structure.
double findMedian() - returns the median of all current elements.
Example 1:
Input:
["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"]
[[],[1],[2],[],[3],[]]
Output: [null,null,null,1.50000,null,2.00000]
Example 2:
Input:
["MedianFinder","addNum","findMedian","addNum","findMedian"]
[[],[2],[],[3],[]]
Output: [null,null,2.00000,null,2.50000]
Idea: maintain a large root heap and a small root heap. The data enters the small root heap first, and keep the large root heap equal to the small root heap (even number) or one less than the small root heap (odd number).
Here, the large root heap stores a relatively small number, while the small root heap stores a relatively large number. The heap top of the large root heap and the heap top of the small root heap are two adjacent numbers, which can be taken to the median by dynamic adjustment.
If the number of large and small root heaps is equal, send a data to the root heap. If the new data is larger than the top of the small heap, send it directly to the small root heap. Otherwise, send it to the large root heap first, and then adjust the large root heap and put the maximum number into the small root heap.
If the small root pile is one more than the large root pile, judge whether this number is larger than the top of the small pile. If it is large, send it to the small root pile first, and then send a minimum number from the small root pile to the large root pile, otherwise directly send it to the large root pile.
type minHeap []int type maxHeap []int func (h minHeap) Len() int { return len(h) } func (h maxHeap) Len() int { return len(h) } func (h maxHeap) Less(i, j int) bool { return h[i] > h[j] } func (h minHeap) Less(i, j int) bool { return h[i] < h[j] } func (h maxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h minHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *minHeap) Push(x interface{}) { *h = append(*h, x.(int)) } func (h *maxHeap) Push(x interface{}) { *h = append(*h, x.(int)) } func (h *maxHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } func (h *minHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } type MedianFinder struct { maxH *maxHeap minH *minHeap } /** initialize your data structure here. */ func Constructor() MedianFinder { return MedianFinder{ new(maxHeap), new(minHeap), } } func (this *MedianFinder) AddNum(num int) { if this.minH.Len()==this.maxH.Len(){ if this.minH.Len()==0||num>(*this.maxH)[0]{ heap.Push(this.minH,num) }else{ heap.Push(this.maxH,num) x := heap.Pop(this.maxH) heap.Push(this.minH,x) } }else { if num> (*this.minH)[0]{ heap.Push(this.minH,num) x:=heap.Pop(this.minH) heap.Push(this.maxH,x) }else{ heap.Push(this.maxH,num) } } } func (this *MedianFinder) FindMedian() float64 { if this.minH.Len()==this.maxH.Len(){ return float64((*this.maxH)[0])/2.0 + float64((*this.minH)[0])/2.0 }else{ return float64((*this.minH)[0]) } }
Title Source: https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof