leetcode每日一题
7月
1833. 雪糕的最大数量
5801. 消灭怪物的最大数量
1418. 点菜展示表
1711. 大餐计数
5792. 统计平方和三元组的数目
274. H 指数
面试题 10.02. 变位词组
6月
1744. 你能在你最喜欢的那天吃到你最喜欢的糖果吗?
42. 接雨水
206. 反转链表
234. 回文链表
141. 环形链表
474. 一和零
5777. 使数组元素相等的减少操作次数
5776. 判断矩阵经轮转后是否一致
1897. 重新分配字符使所有字符串都相等
752. 打开转盘锁
5781. 删除一个字符串中所有出现的给定子字符串
5789. 你完成的完整对局数
5788. 字符串中的最大奇数
852. 山脉数组的峰顶索引
1894. 找到需要补充粉笔的学生编号
5786. 可移除字符的最大数目
1893. 检查是否区域内所有整数都被覆盖
1899. 合并若干三元组以形成目标三元组
5799. 最美子字符串的数目
5780. 删除一个元素使数组严格递增
5月
342. 4的幂
231. 2 的幂
560. 和为K的子数组
141. 环形链表
1074. 元素和为目标值的子矩阵数量
461. 汉明距离
1190. 反转每对括号间的子串
664. 奇怪的打印机
1787. 使所有区间的异或结果为零(放弃治疗)
1707. 与数组中元素的最大异或值
810. 黑板异或游戏
1035. 不相交的线
692. 前K个高频单词
1738. 找出第 K 大的异或坐标值
993. 二叉树的堂兄弟节点
13. 罗马数字转整数
1442. 形成两个异或相等数组的三元组数目
12. 整数转罗马数字
1269. 停在原地的方案数
1734. 解码异或后的排列
1310. 子数组异或查询
872. 叶子相似的树
vditor使用说明
645. 错误的集合
930. 和相同的二元子数组
5793. 迷宫中离入口最近的出口
5843. 作为子字符串出现在单词中的字符串数目
5832. 构造元素不等于两相邻元素平均值的数组
5851. 找出不同的二进制字符串
5850. 找出数组的最大公约数
5835. 最大方阵和
n个人匹配,两两匹配,匹配多轮
本文档使用 MrDoc 发布
-
+
首页
692. 前K个高频单词
# 题目 ## 692. 前 K 个高频单词 [https://leetcode-cn.com/problems/top-k-frequent-words/](https://leetcode-cn.com/problems/top-k-frequent-words/) 给一非空的单词列表,返回前 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 次。 ``` 注意: ``` 假定 k 总为有效值, 1 ≤ k ≤ 集合元素数。 输入的单词均由小写字母组成。 ``` # 题解 ## 思路 将字符串用哈希表存起来,再进行排序。 ## 代码 ```javascript /** * @param {string[]} words * @param {number} k * @return {string[]} */ var topKFrequent = function(words, k) { const map = new Map(); // 哈希表 words.forEach(word => { map.set(word, (map.get(word) || 0) + 1) }); const res = []; for(const key of map.keys()){ res.push(key); } // 排序 res.sort((a, b) => { return map.get(a) === map.get(b) ? a.localeCompare(b) : map.get(b) - map.get(a); }); return res.slice(0, k); }; ``` ## 官方 ### 方法一:哈希表 + 排序 **思路及算法** 我们可以预处理出每一个单词出现的频率,然后依据每个单词出现的频率降序排序,最后返回前 kkk 个字符串即可。 具体地,我们利用哈希表记录每一个字符串出现的频率,然后将哈希表中所有字符串进行排序,排序时,如果两个字符串出现频率相同,那么我们让两字符串中字典序较小的排在前面,否则我们让出现频率较高的排在前面。最后我们只需要保留序列中的前 kkk 个字符串即可。 **代码** ```javascript var topKFrequent = function(words, k) { const cnt = new Map(); for (const word of words) { cnt.set(word, (cnt.get(word) || 0) + 1); } const rec = []; for (const entry of cnt.keys()) { rec.push(entry); } rec.sort((word1, word2) => { return cnt.get(word1) === cnt.get(word2) ? word1.localeCompare(word2) : cnt.get(word2) - cnt.get(word1); }) return rec.slice(0, k); }; ``` ### 方法二:优先队列 **思路及算法** 对于前 kkk 大或前 kkk 小这类问题,有一个通用的解法:优先队列。优先队列可以在 O(logn)O(\log n)O(logn) 的时间内完成插入或删除元素的操作(其中 nnn 为优先队列的大小),并可以 O(1)O(1)O(1) 地查询优先队列顶端元素。 在本题中,我们可以创建一个小根优先队列(顾名思义,就是优先队列顶端元素是最小元素的优先队列)。我们将每一个字符串插入到优先队列中,如果优先队列的大小超过了 kkk,那么我们就将优先队列顶端元素弹出。这样最终优先队列中剩下的 kkk 个元素就是前 kkk 个出现次数最多的单词。 **代码** ```java class Solution { public List<String> topKFrequent(String[] words, int k) { Map<String, Integer> cnt = new HashMap<String, Integer>(); for (String word : words) { cnt.put(word, cnt.getOrDefault(word, 0) + 1); } PriorityQueue<Map.Entry<String, Integer>> pq = new PriorityQueue<Map.Entry<String, Integer>>(new Comparator<Map.Entry<String, Integer>>() { public int compare(Map.Entry<String, Integer> entry1, Map.Entry<String, Integer> entry2) { return entry1.getValue() == entry2.getValue() ? entry2.getKey().compareTo(entry1.getKey()) : entry1.getValue() - entry2.getValue(); } }); for (Map.Entry<String, Integer> entry : cnt.entrySet()) { pq.offer(entry); if (pq.size() > k) { pq.poll(); } } List<String> ret = new ArrayList<String>(); while (!pq.isEmpty()) { ret.add(pq.poll().getKey()); } Collections.reverse(ret); return ret; } } ```
czbiao
2021年5月20日 22:33
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
阅读量
次
本站总访问量
次
本站访客数
人次
Markdown文件
分享
链接
类型
密码
更新密码