Skip to content

Commit 632770a

Browse files
committed
feat(soobing): week1 > top-k-frequent-elements
1 parent 347d259 commit 632770a

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* 문제 유형: Heap
3+
*
4+
* 문제 설명
5+
* - 가장 빈도수가 많은 K개 Element 추출
6+
*
7+
* 아이디어
8+
* 1) 빈도수 계산하여 index와 함께 Map에 저장, 빈도수를 기준으로 MinHeap 구성
9+
* 2) 빈도수 Map을 순회하면서 MinHeap에 추가 + MinHeap의 크기가 K를 초과하면 최소값 제거 (미리미리 빈도수가 많은 K개 Element를 만들어나가는 형식)
10+
* 3) MinHeap에 남아있는 Element들의 index를 반환
11+
*
12+
* 시간 복잡도: O(NlogK)
13+
* 공간 복잡도: O(N)
14+
*/
15+
class MinHeap {
16+
heap: [number, number][] = [];
17+
18+
insert(item: [number, number]) {
19+
this.heap.push(item);
20+
this.bubbleUp();
21+
}
22+
23+
private bubbleUp() {
24+
let index = this.heap.length - 1;
25+
while (index > 0) {
26+
const parentIndex = Math.floor((index - 1) / 2);
27+
if (this.heap[index][0] >= this.heap[parentIndex][0]) break;
28+
[this.heap[index], this.heap[parentIndex]] = [
29+
this.heap[parentIndex],
30+
this.heap[index],
31+
];
32+
index = parentIndex;
33+
}
34+
}
35+
36+
extractMin(): [number, number] | undefined {
37+
if (this.heap.length === 0) return undefined;
38+
const min = this.heap[0];
39+
const end = this.heap.pop();
40+
if (this.heap.length > 0 && end !== undefined) {
41+
this.heap[0] = end;
42+
this.sinkDown(0);
43+
}
44+
return min;
45+
}
46+
47+
private sinkDown(index: number) {
48+
const length = this.heap.length;
49+
while (true) {
50+
let left = 2 * index + 1;
51+
let right = 2 * index + 2;
52+
let smallest = index;
53+
54+
if (left < length && this.heap[left][0] < this.heap[smallest][0]) {
55+
smallest = left;
56+
}
57+
if (right < length && this.heap[right][0] < this.heap[smallest][0]) {
58+
smallest = right;
59+
}
60+
if (index === smallest) break;
61+
62+
[this.heap[index], this.heap[smallest]] = [
63+
this.heap[smallest],
64+
this.heap[index],
65+
];
66+
index = smallest;
67+
}
68+
}
69+
70+
peek(): [number, number] | undefined {
71+
return this.heap[0];
72+
}
73+
74+
size(): number {
75+
return this.heap.length;
76+
}
77+
}
78+
function topKFrequent(nums: number[], k: number): number[] {
79+
const freqMap = new Map<number, number>();
80+
for (const num of nums) {
81+
freqMap.set(num, (freqMap.get(num) ?? 0) + 1);
82+
}
83+
84+
const minHeap = new MinHeap();
85+
for (const [num, count] of freqMap.entries()) {
86+
minHeap.insert([count, num]);
87+
if (minHeap.size() > k) {
88+
minHeap.extractMin();
89+
}
90+
}
91+
92+
return minHeap.heap.map(([_, num]) => num);
93+
}

0 commit comments

Comments
 (0)