1
+ class Heap {
2
+ constructor ( compare ) {
3
+ this . data = [ ] ;
4
+ this . compare = compare ;
5
+ }
6
+
7
+ size ( ) {
8
+ return this . data . length ;
9
+ }
10
+
11
+ peek ( ) {
12
+ return this . data [ 0 ] ;
13
+ }
14
+
15
+ push ( val ) {
16
+ this . data . push ( val ) ;
17
+ this . _siftUp ( ) ;
18
+ }
19
+
20
+ pop ( ) {
21
+ const top = this . peek ( ) ;
22
+ const bottom = this . data . pop ( ) ;
23
+ if ( this . data . length > 0 ) {
24
+ this . data [ 0 ] = bottom ;
25
+ this . _siftDown ( ) ;
26
+ }
27
+ return top ;
28
+ }
29
+
30
+ _siftUp ( ) {
31
+ let i = this . data . length - 1 ;
32
+ const node = this . data [ i ] ;
33
+ while ( i > 0 ) {
34
+ const parent = Math . floor ( ( i - 1 ) / 2 ) ;
35
+ if ( this . compare ( node , this . data [ parent ] ) ) {
36
+ this . data [ i ] = this . data [ parent ] ;
37
+ i = parent ;
38
+ } else break ;
39
+ }
40
+ this . data [ i ] = node ;
41
+ }
42
+
43
+ _siftDown ( ) {
44
+ let i = 0 ;
45
+ const node = this . data [ 0 ] ;
46
+ const length = this . data . length ;
47
+
48
+ while ( true ) {
49
+ let left = 2 * i + 1 ;
50
+ let right = 2 * i + 2 ;
51
+ let swap = i ;
52
+
53
+ if ( left < length && this . compare ( this . data [ left ] , this . data [ swap ] ) ) {
54
+ swap = left ;
55
+ }
56
+ if ( right < length && this . compare ( this . data [ right ] , this . data [ swap ] ) ) {
57
+ swap = right ;
58
+ }
59
+ if ( swap === i ) break ;
60
+
61
+ this . data [ i ] = this . data [ swap ] ;
62
+ i = swap ;
63
+ }
64
+
65
+ this . data [ i ] = node ;
66
+ }
67
+ }
68
+
69
+ var MedianFinder = function ( ) {
70
+ this . small = new Heap ( ( a , b ) => a > b ) ; // max heap
71
+ this . large = new Heap ( ( a , b ) => a < b ) ; // min heap
72
+ } ;
73
+
74
+ MedianFinder . prototype . addNum = function ( num ) {
75
+ this . small . push ( num ) ;
76
+
77
+ if (
78
+ this . small . size ( ) > 0 &&
79
+ this . large . size ( ) > 0 &&
80
+ this . small . peek ( ) > this . large . peek ( )
81
+ ) {
82
+ this . large . push ( this . small . pop ( ) ) ;
83
+ }
84
+
85
+ if ( this . small . size ( ) > this . large . size ( ) + 1 ) {
86
+ this . large . push ( this . small . pop ( ) ) ;
87
+ }
88
+ if ( this . large . size ( ) > this . small . size ( ) + 1 ) {
89
+ this . small . push ( this . large . pop ( ) ) ;
90
+ }
91
+ } ;
92
+
93
+ MedianFinder . prototype . findMedian = function ( ) {
94
+ if ( this . small . size ( ) > this . large . size ( ) ) {
95
+ return this . small . peek ( ) ;
96
+ }
97
+ if ( this . large . size ( ) > this . small . size ( ) ) {
98
+ return this . large . peek ( ) ;
99
+ }
100
+ return ( this . small . peek ( ) + this . large . peek ( ) ) / 2 ;
101
+ } ;
102
+
103
+
0 commit comments