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;
    }
}
相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
m0_547486663 天前
《数据结构教程》全套 PPT课件2026
数据结构
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法