[路飞]_js算法:leetcode 347-前 K 个高频元素

123 阅读1分钟

leetcode 347. 前 K 个高频元素

问题描述: 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2:

输入: nums = [1], k = 1
输出: [1]

思路一: 直接用js数组方法来写

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
// var topKFrequent = function(nums, k) {

// };
var topKFrequent = function (nums, k) {
  var map = new Map()
  var len = nums.length
  for (var i = 0; i < len; i++) {
    map.set(nums[i], (map.get(nums[i]) || 0) + 1)
  }
  return [...map]
    .sort((a, b) => b[1] - a[1])
    .filter((v, i) => i < k)
    .map(v => v[0])
}

思路二: 堆(小顶堆)

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
// var topKFrequent = function(nums, k) {

// };
var topKFrequent = function (nums, k) {
 let map=new Map();
 for(let i=0;i<nums.length;i++){
     map.set(nums[i],(map.get(nums[i])||0)+1)
 }
 
 let heap=new Heap((a,b)=>map.get(a)<map.get(b));
 for(let item of map.keys()){
     heap.push(item)
 }
//  console.log(heap.getData())
 while(heap.size>k){
     heap.pop()
 }
 return heap.getData()
}
//堆的实现
// 小顶堆

class Heap {
  constructor(cmp) {
      this.data = [];
      this.cmp = cmp;
  }
  get size() {
      return this.data.length;
  }
  get top() {
      return this.data[0];
  }
  getData() {
      return this.data;
  }
  swap(i, j) {
      [this.data[i], this.data[j]] = [this.data[j], this.data[i]];
  }
  // 向上冒泡
  up(i) {
      let index=this.data.length-1;
      while(index>0){
          let p=Math.floor((index-1)/2);
          if(p>=0&&this.cmp(this.data[index],this.data[p])){
              this.swap(index,p);
              index=p;
          }else{
              break;
          }
      }
  }
  // 下沉操作
  down(i) {
    if(this.data.length<2)return;
    let index=0,l=2*index+1,len=this.data.length;
    while(l<len){
      let r=l+1;
      if(r<len&&this.cmp(this.data[r], this.data[l]))l=r;
      if(this.cmp(this.data[index], this.data[l]))break;
      this.swap(index,l)
      index=l;
      l=index*2+1;
    }
  }
  push(item) {
    this.data.push(item);
    this.up();
  }
  //删除堆顶元素
  pop() {
      this.swap(0, this.data.length - 1);
      const res = this.data.pop();//已删除的元素(原来的堆顶元素)
      this.down();
      return res;
  }
}