[路飞]leetcode-692.前K个高频单词

97 阅读1分钟

给一非空的单词列表,返回前 k 个出现次数最多的单词。

返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。掘金

示例 1:

输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i""love" 为出现次数最多的两个单词,均为2次。
    注意,按字母顺序 "i""love" 之前。

示例 2:

输入: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4
输出: ["the", "is", "sunny", "day"]
解析: "the", "is", "sunny""day" 是出现次数最多的四个单词,
    出现次数依次为 4, 3, 21 次。

解题小顶堆:


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.val===b.val) return a.name<b.name
  return a.val>b.val
}

var topKFrequent = function (words, k) {
  let maps=new Map();
  words.forEach(item => {
    if(maps.has(item)){
      maps.set(item,maps.get(item)+1)
    }else{
      maps.set(item,1)
    }
  });
  // console.log(maps)
 
  let heap=new Heap(k,com1)
  maps.forEach((val,name)=>{
   const item={val,name}
   console.log(val)
    if(heap.size()<k||com1(item,heap.top())){
      heap.push(item)
    }
  })
  let res=[]
  while(heap.size()){
    res.unshift(heap.pop().name)
  }
 
  return res
};