2021-05-20 LeetCode每日一题

链接:https://leetcode-cn.com/problems/top-k-frequent-words/

标签:堆、字典序、哈希表

题目

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

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

输入: ["i", "love", "leetcode", "i", "love", "coding"], k = 2
输出: ["i", "love"]
解析: "i" 和 "love" 为出现次数最多的两个单词,均为2次。
注意,按字母顺序 "i" 在 "love" 之前。 输入: ["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 ≤ 集合元素数。
输入的单词均由小写字母组成。

尝试以 O(n log k) 时间复杂度和 O(n) 空间复杂度解决。

分析

题目很好理解,关键题目说O(n log k) 时间复杂度和 O(n) 空间复杂度,这个臣妾恐怕办不到啊。按照我的思路,拿个TreeMap存它,关键是TreeMap是按照键排序的啊,那让它按值排序不就行了吗?听起来好像是个不错的想法,实现起来也不难,那就干它。

class Solution {
public List<String> topKFrequent(String[] words, int k) {
// 按键升序排序
Map<String, Integer> map = new TreeMap<>();
List<String> res = new ArrayList<>(k); for (String word : words) {
map.put(word, map.getOrDefault(word, 0) + 1);
} // 按值降序
List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, (o1, o2) -> {
// map已经默认按键升序,所以这里只需要判断值即可
return o2.getValue().compareTo(o1.getValue());
}); for (Map.Entry<String, Integer> entry : list) {
if (--k < 0) {
break;
}
res.add(entry.getKey());
} return res;
}
}


这个如果用lambda写的话,一行就O了。

class Solution {
public List<String> topKFrequent(String[] words, int k) {
return Arrays.stream(words)
.parallel()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.sorted(Comparator.<Map.Entry<String, Long>>comparingLong(Map.Entry::getValue)
.reversed().thenComparing(Map.Entry::getKey))
.limit(k)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}


但这个结果不咋地。不过看起来这个13ms和27ms击败率已经没啥区别了,都属于垫底的。

这里也可以使用优先级队列来存储,在构造函数里传入排序函数即可。和上面的写法意思大致一样。

class Solution {
public List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> map = new HashMap<>();
List<String> res = new ArrayList<>(k); for (String word : words) {
map.put(word, map.getOrDefault(word, 0) + 1);
} // 优先权队列,指定排序规则
PriorityQueue<String> queue = new PriorityQueue<>((o1, o2) ->
// 这里map.get(o1)和map.get(o2)比较要使用equals,因为在[-128, 127]之间,==才返回true
map.get(o1).equals(map.get(o2)) ? o1.compareTo(o2) : map.get(o2) - map.get(o1)
); for (String values : map.keySet()) {
queue.add(values);
} while (!queue.isEmpty()) {
if (--k < 0) {
break;
} res.add(queue.poll());
} return res;
}
}

692. 前K个高频单词的更多相关文章

  1. Java实现 LeetCode 692 前K个高频单词(map的应用)

    692. 前K个高频单词 给一非空的单词列表,返回前 k 个出现次数最多的单词. 返回的答案应该按单词出现频率由高到低排序.如果不同的单词有相同出现频率,按字母顺序排序. 示例 1: 输入: [&qu ...

  2. LeetCode:前K个高频单词【692】

    LeetCode:前K个高频单词[692] 题目描述 给一非空的单词列表,返回前 k 个出现次数最多的单词. 返回的答案应该按单词出现频率由高到低排序.如果不同的单词有相同出现频率,按字母顺序排序. ...

  3. [Swift]LeetCode692. 前K个高频单词 | Top K Frequent Words

    Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...

  4. [LeetCode] Top K Frequent Words 前K个高频词

    Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted b ...

  5. [LeetCode] Top K Frequent Elements 前K个高频元素

    Given a non-empty array of integers, return the k most frequent elements. For example,Given [1,1,1,2 ...

  6. 【LeetCode题解】347_前K个高频元素(Top-K-Frequent-Elements)

    目录 描述 解法一:排序算法(不满足时间复杂度要求) Java 实现 Python 实现 复杂度分析 解法二:最小堆 思路 Java 实现 Python 实现 复杂度分析 解法三:桶排序(bucket ...

  7. Top K Frequent Elements 前K个高频元素

    Top K Frequent Elements 347. Top K Frequent Elements [LeetCode] Top K Frequent Elements 前K个高频元素

  8. LeetCode:前K个高频元素【347】

    LeetCode:前K个高频元素[347] 题目描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [ ...

  9. 代码题(3)— 最小的k个数、数组中的第K个最大元素、前K个高频元素

    1.题目:输入n个整数,找出其中最小的K个数. 例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 快排思路(掌握): class Solution { public ...

随机推荐

  1. 使用SSH端口做端口转发以及反向隧道

    目录 SSH做本地端口转发 SSH做反向隧道(远程端口转发) 用autossh建立稳定隧道 SSH开启端口转发需要修改 /etc/ssh/sshd_config配置文件,将 GatewayPorts修 ...

  2. 绕过CDN查找网站真实ip

    在渗透测试过程中,经常会碰到网站有CDN的情况.CDN即内容分发网络,主要解决因传输距离和不同运营商节点造成的网络速度性能低下的问题.说的简单点,就是一组在不同运营商之间的对接点上的高速缓存服务器,把 ...

  3. thinkphp之独立日志(tp5.1)

    为了便于分析,File类型的日志还支持设置某些级别的日志信息单独文件记录,以error类型的日志为例,例如: 1.在log.php 中配置 'apart_level' => [ 'error' ...

  4. 【opencv】获取摄像头rstp视频流地址方法

    1.rstp通用地址格式为 : 通用格式 // user : 登录摄像头的用户名 // password:登录摄像头的密码 // ip:摄像头的ip地址 // port:端口号,常用的为554 &qu ...

  5. 设计一个对象池(Anno.XObjectPool)

    设计一个.net对象池   对象池对于创建开销比较大的对象来说很有意义,为了优化程序的运行速度.避免频繁创建销毁开销比较大的对象,我们可以通过对象池来复用创建开销大的对象.对象池的思路比较简单,事先创 ...

  6. 那些好用的 VS Code 插件,究竟是如何提高编码效率的?

    在上一篇文章中我们已经对 vscode 插件有了一个初步的认识与了解了,接下去我们就要"揭秘"一下市面上那些好用的 vscode 插件究竟是如何帮我们提高工作效率的. 本文首发于「 ...

  7. 『居善地』接口测试 — 4、Requests库发送GET请求

    目录 1.使用Requests库发送带参数的GET请求 2.查看GET请求的内容 3.带请求头.参数的Get请求 Requests库GET请求是使用HTTP协议中的GET请求方式对目标网站发起请求. ...

  8. 【BUAA软工】Beta阶段事后分析

    设想与目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 解决的问题 总体解决的问题:新手编程者配置编程环境难.本地编写的代码跨设备同步难.本地ide安装使用过程 ...

  9. mac SSH私钥取消密码(passphrase)

    取消私钥中的密码: 1.使用openssl命令去掉私钥的密码openssl rsa -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa_new 2.备份旧私钥mv ~/.ssh/ ...

  10. 马哥Linux SysAdmin学习笔记(四)

    sed:编辑器 sed:Stream EDitor,行编辑器 用法: sed [option]... 'script' inputfile... script: '地址命令' 常用选项: -n:不输出 ...