本文主要是介绍347.前k个高频元素,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
347.前k个高频元素
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2:
输入: nums = [1], k = 1 输出: [1]
提示:
1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
思路
创建一个优先级队列 pq,它存储的是数组,用于存储元素及其对应的出现次数。队列的排序方式是按照元素的出现次数从小到大排序。
创建一个大小为 k 的结果数组 res,用于存储前 k 个高频元素。
创建一个哈希表 map,用于记录每个元素出现的次数。
遍历 nums 数组,统计每个元素出现的次数,并存储在 map 中。
遍历 map 的键值对,将键值对转化为数组 tmp,其中 tmp[0] 是元素,tmp[1] 是该元素出现的次数。
将 tmp 加入优先级队列 pq 中。
如果队列 pq 的大小超过了 k,则弹出队列中最小的元素(出现次数最少的元素)。
遍历结束后,队列 pq 中剩余的元素就是前 k 个高频元素,将它们依次存入结果数组 res。
返回结果数组 res。
class Solution {public int[] topKFrequent(int[] nums, int k) {// 优先级队列,为了避免复杂 api 操作,pq 存储数组// lambda 表达式设置优先级队列从大到小存储 o1 - o2 为从小到大,o2 - o1 反之PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);int[] res = new int[k]; // 答案数组为 k 个元素Map<Integer, Integer> map = new HashMap<>(); // 记录元素出现次数for(int num : nums) map.put(num, map.getOrDefault(num, 0) + 1);for(var x : map.entrySet()) { // entrySet 获取 k-v Set 集合// 将 kv 转化成数组int[] tmp = new int[2];tmp[0] = x.getKey();tmp[1] = x.getValue();pq.offer(tmp);// 下面的代码是根据小根堆实现的,只保留优先队列的最后的k个,只要超出了k我就将最小的弹出,剩余的k个就是答案if(pq.size() > k) {//poll()和remove一样,不过poll在队列为空的时候不返回错误pq.poll();}}for(int i = 0; i < k; i ++) {res[i] = pq.poll()[0]; // 获取优先队列里的元素}return res;}
}
这篇关于347.前k个高频元素的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!