数据流的中位数 - 堆(优先队列)

// minHeap 中的数的数量比 maxHeap 多一个
type MedianFinder struct {
	minHeap, maxHeap MyHeap
}
 
func Constructor() MedianFinder {
	return MedianFinder{}
}
 
func (this *MedianFinder) AddNum(num int)  {
	minHeap, maxHeap := &this.minHeap, &this.maxHeap
	if minHeap.Len() == 0 || num <= -minHeap.IntSlice[0] {
		heap.Push(minHeap, -num)
		if maxHeap.Len() + 1 < minHeap.Len() {
			heap.Push(maxHeap, -heap.Pop(minHeap).(int))
		}
	} else {
		heap.Push(maxHeap, num)
		if minHeap.Len() < maxHeap.Len() {
			heap.Push(minHeap, -heap.Pop(maxHeap).(int))
		}
	}
}
 
func (this *MedianFinder) FindMedian() float64 {
	minHeap, maxHeap := this.minHeap, this.maxHeap
	if (minHeap.Len() + maxHeap.Len()) & 1 == 0 {
		return float64(maxHeap.IntSlice[0]-minHeap.IntSlice[0]) / 2
	} else {
		return float64(-minHeap.IntSlice[0])
	}
}
 
type MyHeap struct { sort.IntSlice }
 
func (h *MyHeap) Push(v interface{}) {
	h.IntSlice = append(h.IntSlice, v.(int))
}
 
func (h *MyHeap) Pop() interface{} {
	n := len(h.IntSlice)
	res := h.IntSlice[n - 1]
	h.IntSlice = h.IntSlice[:n - 1]
	return res
}
 
/**
 * Your MedianFinder object will be instantiated and called as such:
 * obj := Constructor();
 * obj.AddNum(num);
 * param_2 := obj.FindMedian();
 */

数据流的中位数 - 有序集合 + 双指针

type MedianFinder struct {
	nums *redblacktree.Tree
	size int
	left, right iterator
}
 
 
func Constructor() MedianFinder {
	return MedianFinder{ nums: redblacktree.NewWithIntComparator() }
}
 
func (this *MedianFinder) AddNum(num int)  {
	if count, has := this.nums.Get(num); has {
		this.nums.Put(num, count.(int) + 1)
	} else {
		this.nums.Put(num, 1)
	}
	if this.size == 0 {
		it := this.nums.Iterator()
		it.Next()
		this.left = iterator{ it, 1 }
		this.right = this.left
	} else if this.size & 1 == 1 {
		if num < this.left.Key().(int) {
			this.left.prev()
		} else {
			this.right.next()
		}
	} else {
		if this.left.Key().(int) < num && num < this.right.Key().(int) {
			this.left.next()
			this.right.prev()
		} else if num >= this.right.Key().(int) {
			this.left.next()
		} else {
			this.right.prev()
			this.left = this.right
		}
	}
	this.size++
}
 
func (this *MedianFinder) FindMedian() float64 {
	return float64(this.left.Key().(int) + this.right.Key().(int)) / 2
}
 
type iterator struct {
	redblacktree.Iterator
	count int
}
 
func (it *iterator) prev() {
	if it.count > 1 {
		it.count--
	} else {
		it.Prev()
		it.count = it.Value().(int)
	}
}
 
func (it *iterator) next() {
	if it.count < it.Value().(int) {
		it.count++
	} else {
		it.Next()
		it.count = 1
	}
}
 
/**
 * Your MedianFinder object will be instantiated and called as such:
 * obj := Constructor();
 * obj.AddNum(num);
 * param_2 := obj.FindMedian();
 */