本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
题目
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/to…
给一非空的单词列表,返回前 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 ≤ 集合元素数。
- 输入的单词均由小写字母组成。
扩展练习:
尝试以O(n log k)时间复杂度和O(n)空间复杂度解决。
问题分析
这道题意思很明确了,根据单词出现的次数排序,次数相同的看字母顺序,最后取前k个
遍历数组,将单词及单词出现次数放在Map中,把Map根据value排序,value相同的根据字母排序,最后取前k个key值就可以了,思路也非常清晰
public class Solution {
public List<String> topKFrequent(String[] words, int k) {
return Arrays.stream(words)
.collect(Collectors.groupingBy(String::toString, TreeMap::new, Collectors.counting()))
.entrySet().stream()
.sorted(
Entry.<String, Long>comparingByValue().reversed().
).map(Entry::getKey).collect(Collectors.toList()).subList(0, k);
}
}
总结
如果用lambda表达式来写,一行代码就可以解决问题,这种不一定符合算法题的解题要求,但是平时写代码的时候会经常用到这些东西
groupingBy的作用是分组,它返回的是一个map。groupingby可以有三个参数,第一个表示要分组的字段,是返回结果的key,第二个表示返回结果的类型,第三个是返回结果的value值collet可以将stream再次转化为集合类Entry.<String, Long>comparingByValue()表示将map根据value值排序,map根据key值排序的话用Entry.<String, Long>comparingByKey()reversed表示反序,原来是从小到大,变成从大到小map可以对集合类进行转化,或者说对集合中的元素进行操作