1
1
/**
2
- * Hash Map - Frequency Counter
3
- * Matrix - Bucket
4
- * Time O(N^2) | Space O(N^2)
2
+ * Set - Frequency Counter
3
+ * Time O(NlogN) | Space O(N)
5
4
* https://leetcode.com/problems/top-k-frequent-elements/
6
5
* @param {number[] } nums
7
6
* @param {number } k
8
7
* @return {number[] }
9
8
*/
10
- var topKFrequent = ( nums , k ) => {
11
- const map = getFrequencyMap ( nums ) ; /* Time O(N) | Space O(N) */
12
- const bucket = getBucket ( nums , map ) ; /* Time O(N) | Space O(N^2) */
13
-
14
- return getTopK ( bucket , k ) ; /* Time O(N^2) | Space O(K) */
9
+ var topKFrequent = function ( nums , k ) {
10
+ let frequency = { }
11
+ for ( let i = 0 ; i < nums . length ; i ++ ) {
12
+ if ( frequency . hasOwnProperty ( nums [ i ] ) ) frequency [ nums [ i ] ] += 1 ;
13
+ else frequency [ nums [ i ] ] = 1 ;
14
+ }
15
+ let result = Object . keys ( frequency ) . map ( ( key ) => [ Number ( key ) , frequency [ key ] ] ) ;
16
+ let sortedResult = result . sort ( ( a , b ) => {
17
+ return b [ 1 ] - a [ 1 ]
18
+ } )
19
+ let output = [ ]
20
+ for ( let i = 0 ; i < k ; i ++ ) {
21
+ output . push ( sortedResult [ i ] [ 0 ] )
22
+ }
23
+ return output ;
15
24
} ;
16
-
17
- var getFrequencyMap = ( nums , map = new Map ( ) ) => {
18
- for ( const num of nums ) { /* Time O(N) */
19
- const count = ( map . get ( num ) || 0 ) + 1 ;
20
-
21
- map . set ( num , count ) ; /* Space O(N) */
22
- }
23
-
24
- return map ;
25
- } ;
26
-
27
- const getBucket = ( nums , map ) => {
28
- const bucket = new Array ( nums . length + 1 ) . fill ( )
29
- . map ( ( ) => [ ] ) ;
30
-
31
- for ( const [ num , count ] of map . entries ( ) ) { /* Time O(N) */
32
- bucket [ count ] . push ( num ) ; /* Space O(N * N) */
33
- }
34
-
35
- return bucket . reverse ( ) ; /* Time O(N) */
36
- } ;
37
-
38
- var getTopK = ( bucket , k , topK = [ ] ) => {
39
- for ( const count of bucket ) { /* Time O(N) */
40
- for ( const num of count ) { /* Time O(N) */
41
- const isAtCapacity = topK . length === k ;
42
- if ( isAtCapacity ) break ;
43
-
44
- topK . push ( num ) ; /* Space O(K) */
45
- }
46
- }
47
-
48
- return topK ;
49
- } ;
50
-
51
- /**
52
- * Hash Map - Frequency Counter
53
- * Heap - Min Priority Queue
54
- * Time O(N * log(K)) | Space O(N + K)
55
- * https://leetcode.com/problems/top-k-frequent-elements/
56
- * @param {number[] } nums
57
- * @param {number } k
58
- * @return {number[] }
59
- */
60
- var topKFrequent = ( nums , k ) => {
61
- const isAtCapacity = k === nums . length
62
- if ( isAtCapacity ) return nums ;
63
-
64
- const map = getFrequencyMap ( nums ) ; /* Time O(N) | Space O(N) */
65
- const minHeap = getMinHeap ( map , k ) ; /* Time O(N * log(K)) | Space O(K) */
66
-
67
- return getTopK ( minHeap , k ) ; /* Time O(K * log(K)) | Space O(K) */
68
- }
69
-
70
-
71
- var getFrequencyMap = ( nums , map = new Map ( ) ) => {
72
- for ( const num of nums ) { /* Time O(N) */
73
- const count = ( map . get ( num ) || 0 ) + 1 ;
74
-
75
- map . set ( num , count ) ; /* Space O(N) */
76
- }
77
-
78
- return map ;
79
- } ;
80
-
81
- const getMinHeap = ( map , k ) => {
82
- const minHeap = new MinPriorityQueue ( { priority : ( [ num , count ] ) => count } ) ;
83
-
84
- for ( const [ num , count ] of map . entries ( ) ) { /* Time O(N) */
85
- minHeap . enqueue ( [ num , count ] ) ; /* Time O(log(K))) | Space O(K) */
86
-
87
- const isOverCapacity = k < minHeap . size ( ) ;
88
- if ( isOverCapacity ) minHeap . dequeue ( ) ; /* Time O(log(K))) */
89
- }
90
-
91
- return minHeap ;
92
- }
93
-
94
- var getTopK = ( minHeap , k , topK = [ ] ) => {
95
- while ( k ) { /* Time O(K) */
96
- const [ num , count ] = minHeap
97
- . dequeue ( ) . element ; /* Time O(log(K))) */
98
-
99
- topK . push ( num ) ; /* Space O(K) */
100
- k -- ;
101
- }
102
-
103
- return topK
104
- }
105
-
106
- /**
107
- * Hash Map - Frequency Counter
108
- * Sort - Quick Select - Average Time O(N) | Worst Time O(N^2)
109
- * Time O(N^2) | Space O(N)
110
- * https://leetcode.com/problems/top-k-frequent-elements/
111
- * @param {number[] } nums
112
- * @param {number } k
113
- * @return {number[] }
114
- */
115
- var topKFrequent = ( nums , k ) => {
116
- const map = getFrequencyMap ( nums ) ; /* Time O(N) | Space O(N) */
117
- const distinctNums = [ ...map . keys ( ) ] ; /* Time O(N) | Space O(N) */
118
- const [ left , right , kSmallest ] = [ 0 , ( map . size - 1 ) , ( map . size - k ) ] ;
119
-
120
- quickselect ( left , right , kSmallest , distinctNums , map ) ; /* Time O(N || N^2) | Space O(log(N)) */
121
-
122
- const [ start , end ] = [ kSmallest , map . size ] ;
123
- const topK = distinctNums . slice ( start , end ) ; /* Time O(K) | Space O(K) */
124
-
125
- return topK ;
126
- }
127
-
128
- var getFrequencyMap = ( nums , map = new Map ) => {
129
- for ( const num of nums ) { /* Time O(N) */
130
- const count = ( map . get ( num ) || 0 ) + 1 ;
131
-
132
- map . set ( num , count ) ; /* Space O(N) */
133
- }
134
-
135
- return map ;
136
- } ;
137
-
138
- const quickselect = ( left , right , kSmallest , nums , map ) => {
139
- const isBaseCase = left === right ;
140
- if ( isBaseCase ) return ;
141
-
142
- const mid = partition ( left , right , nums , map ) ; /* Time O(N) */
143
-
144
- const isTarget = mid === kSmallest ;
145
- if ( isTarget ) return ;
146
-
147
- const isTargetGreater = mid < kSmallest ;
148
- if ( isTargetGreater ) quickselect ( /* Time O(N * N) | Space O(log(N)) */
149
- ( mid + 1 ) , right , kSmallest , nums , map
150
- ) ;
151
-
152
- const isTargetLess = kSmallest < mid ;
153
- if ( isTargetLess ) quickselect ( /* Time O(N * N) | Space O(log(N)) */
154
- left , ( mid - 1 ) , kSmallest , nums , map
155
- ) ;
156
-
157
- }
158
-
159
- const partition = ( left , right , nums , map ) => {
160
- const mid = ( left + right ) >> 1 ;
161
- const guess = nums [ mid ] ;
162
- const count = map . get ( guess ) ;
163
-
164
- swap ( nums , mid , right ) ;
165
-
166
- const pivot = getPivot ( left , right , count , nums , map ) ; /* Time O(N) */
167
-
168
- swap ( nums , pivot , right ) ;
169
-
170
- return pivot ;
171
- }
172
-
173
- const swap = ( arr , left , right ) => [ arr [ left ] , arr [ right ] ] = [ arr [ right ] , arr [ left ] ] ;
174
-
175
- const getPivot = ( left , right , count , nums , map , pivot = left ) => {
176
- for ( let index = left ; index <= right ; index ++ ) { /* Time O(N) */
177
- const num = nums [ index ] ;
178
- const numCount = map . get ( num ) ;
179
-
180
- const canSkip = count <= numCount ;
181
- if ( canSkip ) continue ;
182
-
183
- swap ( nums , pivot , index ) ;
184
- pivot ++ ;
185
- }
186
-
187
- return pivot ;
188
- }
0 commit comments