347. 前 K 个高频元素【中等】

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

**输入:**nums = [1,1,1,2,2,3], k = 2

输出:[1,2]

示例 2:

**输入:**nums = [1], k = 1

输出:[1]

示例 3:

**输入:**nums = [1,2,1,2,1,2,3,1,3,2], k = 2

输出:[1,2]

一、最小堆

思路:

这是一个Top K 问题 ,优先想到的就是使用最小堆/最大堆 ,使用优先级队列 PriorityQueue实现,PriorityQueue 虽然继承队列接口,但实际底层封装的是树结构,所以它满足堆的所有特性,它就是堆的具体实现。

我们首先创建一个哈希map,key存数组元素,value 存出现的频率,使用map辅助,一是能记录频率,二是能去重。再创建一个最小堆,用map 中的value 来排序。在遍历map 的键数组的过程中,让堆的大小为k,超出k 时移除堆顶元素,最后得到的堆就是包含前k 个高频元素的堆了。

时间复杂度O(n log k),因为堆是树结构,所以插入删除都是log k,当数组元素都不同时遍历耗时n

代码:

java 复制代码
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        // 使用map辅助,一是能记录频率,二是能去重
        Map<Integer, Integer> frequentMap = new HashMap<>();

        for(int num : nums){
            frequentMap.put(num, frequentMap.getOrDefault(num, 0) + 1);
        }

        PriorityQueue<Integer> minHeap = new PriorityQueue<>(
            (a, b) -> frequentMap.get(a) - frequentMap.get(b)
        );

        // map的keySet帮助去重了
        for(int num : frequentMap.keySet()){
            minHeap.offer(num);

            if(minHeap.size() > k){
                minHeap.poll(); 
            }
        }

        int[] reslut = new int[k];
        for(int i = 0; i < k; i++){
            reslut[i] = minHeap.poll();
        }
        
        return reslut;
    }
}
相关推荐
Wei&Yan2 分钟前
数据结构——顺序表(静/动态代码实现)
数据结构·c++·算法·visual studio code
团子的二进制世界36 分钟前
G1垃圾收集器是如何工作的?
java·jvm·算法
吃杠碰小鸡40 分钟前
高中数学-数列-导数证明
前端·数学·算法
故事不长丨40 分钟前
C#线程同步:lock、Monitor、Mutex原理+用法+实战全解析
开发语言·算法·c#
long31641 分钟前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
近津薪荼42 分钟前
dfs专题4——二叉树的深搜(验证二叉搜索树)
c++·学习·算法·深度优先
熊文豪1 小时前
探索CANN ops-nn:高性能哈希算子技术解读
算法·哈希算法·cann
熊猫_豆豆1 小时前
YOLOP车道检测
人工智能·python·算法
艾莉丝努力练剑1 小时前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
偷吃的耗子2 小时前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn