Skip to content

Commit 38eca3e

Browse files
committed
347.前-k-个高频元素 (二刷)
1 parent 2a23453 commit 38eca3e

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

vs-lt/347.前-k-个高频元素.js

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* @lc app=leetcode.cn id=347 lang=javascript
3+
*
4+
* [347] 前 K 个高频元素
5+
*/
6+
7+
// @lc code=start
8+
/**
9+
* @param {number[]} nums
10+
* @param {number} k
11+
* @return {number[]}
12+
*/
13+
var topKFrequent = function(nums, k) {
14+
const map = new Map();
15+
16+
for (let i = 0; i < nums.length; i++) {
17+
const curr = nums[i];
18+
map.set(curr, (map.get(curr) || 0) + 1);
19+
}
20+
21+
// 优先队列 (小顶堆)
22+
const heap = new MinHeap();
23+
24+
for (const item of map.entries()) {
25+
heap.push(item);
26+
27+
if (heap.size() > k) {
28+
heap.pop();
29+
}
30+
}
31+
32+
const result = [];
33+
34+
for (let i = heap.size() - 1; i >= 0; i--) {
35+
const item = heap.pop();
36+
result.push(item[0]);
37+
}
38+
39+
return result;
40+
};
41+
42+
class MinHeap {
43+
constructor() {
44+
this.queue = [];
45+
}
46+
47+
push(item) {
48+
if (item) {
49+
this.queue.push(item);
50+
// 执行上移操作
51+
this.siftUp(this.size() - 1);
52+
}
53+
}
54+
55+
pop() {
56+
if (this.size() === 0) {
57+
return undefined;
58+
}
59+
if (this.size() === 1) {
60+
return this.queue.pop();
61+
}
62+
// 被移除值(堆顶)
63+
const removedValue = this.queue[0];
64+
// 弹出队列尾部的元素, 放到队头
65+
this.queue[0] = this.queue.pop();
66+
// 执行下沉操作
67+
this.siftDown(0);
68+
69+
return removedValue;
70+
}
71+
72+
// 上移操作
73+
siftUp(index) {
74+
const parentIndex = index === 0 ? null : (index - 1) >> 1;
75+
const parentValue = this.queue[parentIndex];
76+
const currValue = this.queue[index];
77+
78+
if (index > 0 && currValue[1] < parentValue[1]) {
79+
swap(this.queue, index, parentIndex);
80+
// 继续执行上移操作
81+
this.siftUp(parentIndex);
82+
}
83+
}
84+
85+
// 下移
86+
siftDown(index) {
87+
const left = index * 2 + 1;
88+
const right = index * 2 + 2;
89+
const size = this.size();
90+
let largest = index;
91+
92+
if (left < size && this.queue[left][1] < this.queue[largest][1]) {
93+
largest = left;
94+
}
95+
if (right < size && this.queue[right][1] < this.queue[largest][1]) {
96+
largest = right;
97+
}
98+
99+
if (largest !== index) {
100+
swap(this.queue, index, largest);
101+
this.siftDown(largest);
102+
}
103+
}
104+
105+
size() {
106+
return this.queue.length;
107+
}
108+
}
109+
110+
function swap(array, i, j) {
111+
const temp = array[i];
112+
array[i] = array[j];
113+
array[j] = temp;
114+
}
115+
// @lc code=end

0 commit comments

Comments
 (0)