给一非空的单词列表,返回前 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, 2 和 1 次。
package com.leecode; import java.util.*; public class Leecode692 { public static void main(String[] args) { //java 中堆的常用操作 //创建最小堆 PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(); //默认创建最小堆 //创建最大堆 PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(Collections.<Integer>reverseOrder()); //添加元素 minHeap.add(10); minHeap.add(11); minHeap.add(9); minHeap.add(8); minHeap.add(7); minHeap.add(6); minHeap.add(5); minHeap.add(14); minHeap.add(13); System.out.printf(minHeap.toString()); } private HashMap<String,Integer> hashMap; public List<String> topKFrequent(String[] words, int k){ // 结果 ArrayList<String> res = new ArrayList<>(); // 统计频率 hashMap = new HashMap<>(); for(String key:words) { if(hashMap.containsKey(key)) { hashMap.put(key,hashMap.get(key)+1); }else { hashMap.put(key,1); } } // 用小顶堆优先级队列来解决 // 相同频率下,字母顺序高的在前 PriorityQueue<String> queue = new PriorityQueue<>(k,(a,b)->compareTo(a,b)); // 维持一个小顶堆 for(String key:hashMap.keySet()) { if(k>queue.size()) { queue.offer(key); }else if(compareTo(key,queue.peek())>0) { queue.poll(); queue.offer(key); } } // 得到结果 while(!queue.isEmpty()) { res.add(0,queue.poll()); } return res; } private int compareTo(String a,String b) { Integer value_a = hashMap.get(a); Integer value_b = hashMap.get(b); if(value_a.equals(value_b)) { return b.compareTo(a); }else { return Integer.compare(value_a, value_b); } } }