Skip to content

Commit 50d2519

Browse files
committed
solution for find median from data stream - two heaps. rename filename for insertion sort solution
1 parent 40174f2 commit 50d2519

2 files changed

+138
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// https://leetcode.com/problems/find-median-from-data-stream/
2+
3+
package main
4+
5+
type MedianFinder struct {
6+
qLow, qHigh *PriorityQueue
7+
}
8+
9+
/** initialize your data structure here. */
10+
func Constructor() MedianFinder {
11+
return MedianFinder{
12+
qLow: NewQueue(func(i, j int) bool { return i > j }),
13+
qHigh: NewQueue(func(i, j int) bool { return i < j }),
14+
}
15+
}
16+
17+
func (this *MedianFinder) AddNum(num int) {
18+
this.qLow.Push(num)
19+
20+
v, _ := this.qLow.Top()
21+
this.qHigh.Push(v)
22+
this.qLow.Pop()
23+
24+
if this.qLow.Len() < this.qHigh.Len() {
25+
v, _ := this.qHigh.Top()
26+
this.qLow.Push(v)
27+
this.qHigh.Pop()
28+
}
29+
}
30+
31+
func (this *MedianFinder) FindMedian() float64 {
32+
if this.qLow.Len() > this.qHigh.Len() {
33+
v, _ := this.qLow.Top()
34+
return float64(v)
35+
}
36+
vl, _ := this.qLow.Top()
37+
vh, _ := this.qHigh.Top()
38+
return float64(vl+vh) / 2
39+
}
40+
41+
type PriorityQueue struct {
42+
compareFn func(i, j int) bool
43+
data []int
44+
}
45+
46+
func NewQueue(compareFn func(i, j int) bool) *PriorityQueue {
47+
return &PriorityQueue{
48+
compareFn: compareFn,
49+
data: make([]int, 0),
50+
}
51+
}
52+
53+
func (q *PriorityQueue) Len() int {
54+
return len(q.data)
55+
}
56+
57+
func (q *PriorityQueue) Top() (int, bool) {
58+
if len(q.data) > 0 {
59+
return q.data[0], true
60+
}
61+
return 0, false
62+
}
63+
64+
func (q *PriorityQueue) Push(num int) {
65+
q.data = append(q.data, num)
66+
q.siftUp()
67+
}
68+
69+
func (q *PriorityQueue) Pop() (int, bool) {
70+
if len(q.data) == 0 {
71+
return 0, false
72+
}
73+
74+
v := q.data[0]
75+
q.data[0] = q.data[len(q.data)-1]
76+
q.data = q.data[:len(q.data)-1]
77+
q.siftDown()
78+
79+
return v, true
80+
}
81+
82+
func (q *PriorityQueue) siftUp() {
83+
cIdx := len(q.data) - 1 // current index
84+
pIdx := (cIdx - 1) / 2
85+
86+
for cIdx > 0 && q.compareFn(q.data[cIdx], q.data[pIdx]) {
87+
// xor swap (works for integers)
88+
q.data[cIdx] = q.data[cIdx] ^ q.data[pIdx]
89+
q.data[pIdx] = q.data[pIdx] ^ q.data[cIdx]
90+
q.data[cIdx] = q.data[cIdx] ^ q.data[pIdx]
91+
92+
// update indexes
93+
cIdx = pIdx
94+
pIdx = (cIdx - 1) / 2
95+
}
96+
}
97+
98+
func (q *PriorityQueue) siftDown() {
99+
if len(q.data) == 0 {
100+
return
101+
}
102+
103+
cIdx := 0
104+
for {
105+
// left and right indexes
106+
lIdx := cIdx*2 + 1
107+
rIdx := lIdx + 1
108+
109+
// find max
110+
maxIdx := cIdx
111+
if lIdx < len(q.data) && q.compareFn(q.data[lIdx], q.data[maxIdx]) {
112+
maxIdx = lIdx
113+
}
114+
if rIdx < len(q.data) && q.compareFn(q.data[rIdx], q.data[maxIdx]) {
115+
maxIdx = rIdx
116+
}
117+
118+
// swap current with max
119+
if cIdx == maxIdx {
120+
break
121+
}
122+
123+
// xor swap (works for integers)
124+
q.data[cIdx] = q.data[cIdx] ^ q.data[maxIdx]
125+
q.data[maxIdx] = q.data[maxIdx] ^ q.data[cIdx]
126+
q.data[cIdx] = q.data[cIdx] ^ q.data[maxIdx]
127+
128+
// update current index
129+
cIdx = maxIdx
130+
}
131+
}
132+
133+
/**
134+
* Your MedianFinder object will be instantiated and called as such:
135+
* obj := Constructor();
136+
* obj.AddNum(num);
137+
* param_2 := obj.FindMedian();
138+
*/

0 commit comments

Comments
 (0)