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