From 300922d68e3305024755fffb718f5d07a05b70cd Mon Sep 17 00:00:00 2001 From: Jamcy123 <1219502823@qq.com> Date: Tue, 23 Aug 2022 11:45:24 +0800 Subject: [PATCH] =?UTF-8?q?347.=E5=89=8DK=E4=B8=AA=E9=AB=98=E9=A2=91?= =?UTF-8?q?=E5=85=83=E7=B4=A0JS=E7=89=88=E6=9C=AC=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0347.前K个高频元素.md | 177 ++++++++++++++------------- 1 file changed, 90 insertions(+), 87 deletions(-) diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md index 1d6a358b..d0a3063a 100644 --- a/problems/0347.前K个高频元素.md +++ b/problems/0347.前K个高频元素.md @@ -263,99 +263,102 @@ func topKFrequent(nums []int, k int) []int { -javaScript: +JavaScript: ```js -/** - * @param {number[]} nums - * @param {number} k - * @return {number[]} - */ -var topKFrequent = function(nums, k) { - const map = new Map(); - - for(const num of nums) { - map.set(num, (map.get(num) || 0) + 1); - } - - // 创建小顶堆 - const priorityQueue = new PriorityQueue((a, b) => a[1] - b[1]); - - // entry 是一个长度为2的数组,0位置存储key,1位置存储value - for (const entry of map.entries()) { - priorityQueue.push(entry); - if (priorityQueue.size() > k) { - priorityQueue.pop(); +// js 没有堆 需要自己构造 +class Heap { + constructor(compareFn) { + this.compareFn = compareFn; + this.queue = []; } - } - const ret = []; + // 添加 + push(item) { + // 推入元素 + this.queue.push(item); - for(let i = priorityQueue.size() - 1; i >= 0; i--) { - ret[i] = priorityQueue.pop()[0]; - } + // 上浮 + let index = this.size() - 1; // 记录推入元素下标 + let parent = Math.floor((index - 1) / 2); // 记录父节点下标 - return ret; + while (parent >= 0 && this.compare(parent, index) > 0) { // 注意compare参数顺序 + [this.queue[index], this.queue[parent]] = [this.queue[parent], this.queue[index]]; + + // 更新下标 + index = parent; + parent = Math.floor((index - 1) / 2); + } + } + + // 获取堆顶元素并移除 + pop() { + // 堆顶元素 + const out = this.queue[0]; + + // 移除堆顶元素 填入最后一个元素 + this.queue[0] = this.queue.pop(); + + // 下沉 + let index = 0; // 记录下沉元素下标 + let left = 1; // left 是左子节点下标 left + 1 则是右子节点下标 + let searchChild = this.compare(left, left + 1) > 0 ? left + 1 : left; + + while (searchChild !== undefined && this.compare(index, searchChild) > 0) { // 注意compare参数顺序 + [this.queue[index], this.queue[searchChild]] = [this.queue[searchChild], this.queue[index]]; + + // 更新下标 + index = searchChild; + left = 2 * index + 1; + searchChild = this.compare(left, left + 1) > 0 ? left + 1 : left; + } + + return out; + } + + size() { + return this.queue.length; + } + + // 使用传入的 compareFn 比较两个位置的元素 + compare(index1, index2) { + // 处理下标越界问题 + if (this.queue[index1] === undefined) return 1; + if (this.queue[index2] === undefined) return -1; + + return this.compareFn(this.queue[index1], this.queue[index2]); + } + +} + +const topKFrequent = function (nums, k) { + const map = new Map(); + + for (const num of nums) { + map.set(num, (map.get(num) || 0) + 1); + } + + // 创建小顶堆 + const heap= new Heap((a, b) => a[1] - b[1]); + + // entry 是一个长度为2的数组,0位置存储key,1位置存储value + for (const entry of map.entries()) { + heap.push(entry); + + if (heap.size() > k) { + heap.pop(); + } + } + + // return heap.queue.map(e => e[0]); + + const res = []; + + for (let i = heap.size() - 1; i >= 0; i--) { + res[i] = heap.pop()[0]; + } + + return res; }; - - -function PriorityQueue(compareFn) { - this.compareFn = compareFn; - this.queue = []; -} - -// 添加 -PriorityQueue.prototype.push = function(item) { - this.queue.push(item); - let index = this.queue.length - 1; - let parent = Math.floor((index - 1) / 2); - // 上浮 - while(parent >= 0 && this.compare(parent, index) > 0) { - // 交换 - [this.queue[index], this.queue[parent]] = [this.queue[parent], this.queue[index]]; - index = parent; - parent = Math.floor((index - 1) / 2); - } -} - -// 获取堆顶元素并移除 -PriorityQueue.prototype.pop = function() { - const ret = this.queue[0]; - - // 把最后一个节点移到堆顶 - this.queue[0] = this.queue.pop(); - - let index = 0; - // 左子节点下标,left + 1 就是右子节点下标 - let left = 1; - let selectedChild = this.compare(left, left + 1) > 0 ? left + 1 : left; - - // 下沉 - while(selectedChild !== undefined && this.compare(index, selectedChild) > 0) { - // 交换 - [this.queue[index], this.queue[selectedChild]] = [this.queue[selectedChild], this.queue[index]]; - index = selectedChild; - left = 2 * index + 1; - selectedChild = this.compare(left, left + 1) > 0 ? left + 1 : left; - } - - return ret; -} - -PriorityQueue.prototype.size = function() { - return this.queue.length; -} - -// 使用传入的 compareFn 比较两个位置的元素 -PriorityQueue.prototype.compare = function(index1, index2) { - if (this.queue[index1] === undefined) { - return 1; - } - if (this.queue[index2] === undefined) { - return -1; - } - - return this.compareFn(this.queue[index1], this.queue[index2]); -} ``` TypeScript: