Find Median from Data Stream

Problem Description

The median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values.

Implement the MedianFinder class:

 

Example 1:

Input
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
[[], [1], [2], [], [3], []]
Output
[null, null, null, 1.5, null, 2.0]

Explanation
MedianFinder medianFinder = new MedianFinder();
medianFinder.addNum(1);    // arr = [1]
medianFinder.addNum(2);    // arr = [1, 2]
medianFinder.findMedian(); // return 1.5 (i.e., (1 + 2) / 2)
medianFinder.addNum(3);    // arr[1, 2, 3]
medianFinder.findMedian(); // return 2.0

 

Constraints:

 

Follow up:

Solution (Go)

type Heap struct {
	Values   []int
	LessFunc func(int, int) bool
}

func (h *Heap) Less(i, j int) bool { return h.LessFunc(h.Values[i], h.Values[j]) }
func (h *Heap) Swap(i, j int)      { h.Values[i], h.Values[j] = h.Values[j], h.Values[i] }
func (h *Heap) Len() int           { return len(h.Values) }
func (h *Heap) Peek() int          { return h.Values[0] }
func (h *Heap) Pop() (v interface{}) {
	h.Values, v = h.Values[:h.Len()-1], h.Values[h.Len()-1]
	return v
}
func (h *Heap) Push(v interface{}) { h.Values = append(h.Values, v.(int)) }

func NewHeap(less func(int, int) bool) *Heap {
	return &Heap{LessFunc: less}
}

type MedianFinder struct {
	smallHeap *Heap
	largeHeap *Heap
}

func Constructor() MedianFinder {
	return MedianFinder{
		smallHeap: NewHeap(func(a, b int) bool { return a > b }),
		largeHeap: NewHeap(func(a, b int) bool { return a < b }),
	}
}

func (this *MedianFinder) AddNum(num int) {
	if this.smallHeap.Len() < this.largeHeap.Len() {
		heap.Push(this.largeHeap, num)
		heap.Push(this.smallHeap, heap.Pop(this.largeHeap))
	} else {
		heap.Push(this.smallHeap, num)
		heap.Push(this.largeHeap, heap.Pop(this.smallHeap))
	}
}

func (this *MedianFinder) FindMedian() float64 {
	if this.smallHeap.Len() == this.largeHeap.Len() {
		return float64(this.smallHeap.Peek()+this.largeHeap.Peek()) / 2.0
	} else {
		return float64(this.largeHeap.Peek())
	}
}