[路飞]leetcode-347.前K个高频元素

120 阅读1分钟

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。力扣原文

示例 1:

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

示例 2:

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

 

提示:

  • 1 <= nums.length <= 105
  • k 的取值范围是 [1, 数组中不相同的元素的个数]
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

 

小顶堆:

class Heap {
    constructor(max,cmp) {
      const defaultCmp = (a, b) => a > b;
      this.list = [];
      //默认大顶堆
      this.cmp = cmp || defaultCmp;
      this.max=max||null
    }
    size() {
      return this.list.length;
    }
    top() {
      return this.list.length === 0 ? null : this.list[0];
    }
    push(val) {
      this.list.push(val);
      if(this.size()>1){
      this.bubbleUp(this.size() - 1);
      }
      if( this.max!==null&&this.size()> this.max)this.pop()
    }
    pop() {
      if (!this.size()) {
        return null;
      } else if (this.size() === 1) {
        return this.list.pop();
      }
      const top = this.list[0];
      this.list[0] = this.list.pop();
      this.bubbleDown(0);
      return top;
    }
    //向上调整
    bubbleUp(idx) {
      while (idx) {
        let parentIdx = (idx-1)>>1;
        if (this.cmp(this.list[parentIdx],this.list[idx] )) {
          this.swap(idx, parentIdx);
          idx = parentIdx;
        } else {
          break;
        }
      }
    }
    //向下调整
    bubbleDown() {
      let cur = 0,leftIdx=1,rightIdx=2,size=this.size()
      while(
       ( leftIdx<size&&this.cmp(this.list[cur],this.list[leftIdx]))||
       ( rightIdx<size&&this.cmp(this.list[cur],this.list[rightIdx]))
      ){
        if(rightIdx<size&&this.cmp(this.list[leftIdx],this.list[rightIdx])){
          this.swap(rightIdx,cur)
          cur=rightIdx
         
        }else{
          this.swap(leftIdx,cur)
          cur=leftIdx
        }
        leftIdx=cur*2+1,rightIdx=cur*2+2
      }
    }
    // 交换
    swap(i, j) {
      [this.list[i], this.list[j]] = [this.list[j], this.list[i]];
    }
  }
  function com1(a,b){
   
    if(a.count===b.count) return b.name>a.name;
    return b.count<a.count
  }
var topKFrequent = function(words, k) {
    let map=new Map();let heap=new Heap(k,com1)
    for (let i = 0; i < words.length; i++) {
        const item=words[i]
        if(map.has(words[i])){
            map.set(item,map.get(item)+1)
        }else{
            map.set(item,1)
        }
    }
    map.forEach((count,name) => {
        heap.push({count,name})
    });
    let result=[];
    while(heap.size()){
      result.unshift(heap.pop().name)
    }
    return result
};

记录次数,然后排序:

var topKFrequent = function(words, k) {
  let map=new Map();let heap=new Heap(k,com1)
  for (let i = 0; i < words.length; i++) {
      const item=words[i]
      if(map.has(words[i])){
          map.set(item,map.get(item)+1)
      }else{
          map.set(item,1)
      }
  }
  let array=Array.from(map),result=[]
  array.sort((a,b)=>b[1]-a[1])
  for (let i = 0; i < k; i++) {
    result.push(array[i][0])
  }
  return result
};