LeetCode Hot100(55/100)——347. 前 K 个高频元素

文章目录

一、题目描述

给定一个整数数组 nums 和一个整数 k,请返回其中出现频率前 k 高的元素。

你可以按任意顺序返回答案。

示例:

复制代码
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

二、题目分析与思路导图

这道题的核心在于 统计元素出现的频率 ,然后找到出现次数最多的 k 个元素。
Top K Frequent Elements
统计频率
使用HashMap
键:元素
值:出现次数
找出前K高频
排序法
小顶堆法
桶排序法


三、解法一:排序法(简单直接)

1. 原理说明

  1. 首先遍历数组,使用 HashMap 统计每个数字的出现次数。
  2. 再将 Map 中的键值对按照出现次数降序排序。
  3. 取出前 k 个元素的键即可。

2. 流程图

开始
使用HashMap统计频率
转换为List>
按value降序排序
取前k个entry的key
返回结果数组

3. 时间复杂度与空间复杂度

  • 时间复杂度:O(N log N),排序占主导。
  • 空间复杂度:O(N),用于存储频率映射。

4. Java代码实现

java 复制代码
import java.util.*;

public class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> freqMap = new HashMap<>();
        for (int num : nums) {
            freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
        }

        List<Map.Entry<Integer, Integer>> entries = new ArrayList<>(freqMap.entrySet());
        entries.sort((a, b) -> b.getValue() - a.getValue());

        int[] res = new int[k];
        for (int i = 0; i < k; i++) {
            res[i] = entries.get(i).getKey();
        }
        return res;
    }
}

四、解法二:最小堆法(推荐做法)

1. 原理说明

利用最小堆(PriorityQueue)的性质,维持大小为 k 的堆结构:

  • 遍历所有元素的频率;
  • 当堆的大小小于 k 时将元素加入;
  • 当堆的大小等于 k 且当前元素的频率大于堆顶频率时,弹出堆顶并添加当前元素;
  • 最后堆中的元素即为出现频率前 k 的元素。

2. 时序图

提取结果 小顶堆操作 建立频率表 输入nums和k 提取结果 小顶堆操作 建立频率表 输入nums和k 遍历nums统计频率 对每个元素频率进行入堆判断 保持堆大小不超过k 输出堆中所有元素

3. 时间复杂度与空间复杂度

  • 时间复杂度:O(N log K),因为堆操作上限为 K。
  • 空间复杂度:O(N),用于哈希表和堆存储。

4. Java代码实现

java 复制代码
import java.util.*;

public class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> freqMap = new HashMap<>();
        for (int num : nums) {
            freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
        }

        PriorityQueue<Map.Entry<Integer, Integer>> heap =
            new PriorityQueue<>(Comparator.comparingInt(Map.Entry::getValue));

        for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {
            heap.offer(entry);
            if (heap.size() > k) {
                heap.poll();
            }
        }

        int[] res = new int[k];
        for (int i = k - 1; i >= 0; i--) {
            res[i] = heap.poll().getKey();
        }
        return res;
    }
}

五、解法三:桶排序法(最优解)

1. 原理说明

桶排序法充分利用频率的离散性:

  1. 统计频率;
  2. 构建一个桶列表,其中桶索引表示频率,桶内容存储出现该频率的数字;
  3. 从高频桶往下搜索,直到收集够 k 个元素。

2. 时间复杂度与空间复杂度

  • 时间复杂度:O(N),因为每个元素都仅遍历一次。
  • 空间复杂度:O(N),用于存储桶。

3. Java代码实现

java 复制代码
import java.util.*;

public class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> freqMap = new HashMap<>();
        for (int num : nums) {
            freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);
        }

        List<List<Integer>> buckets = new ArrayList<>();
        for (int i = 0; i <= nums.length; i++) {
            buckets.add(new ArrayList<>());
        }

        for (Map.Entry<Integer, Integer> entry : freqMap.entrySet()) {
            int freq = entry.getValue();
            buckets.get(freq).add(entry.getKey());
        }

        List<Integer> resList = new ArrayList<>();
        for (int i = buckets.size() - 1; i >= 0 && resList.size() < k; i--) {
            resList.addAll(buckets.get(i));
        }

        int[] res = new int[k];
        for (int i = 0; i < k; i++) {
            res[i] = resList.get(i);
        }
        return res;
    }
}

六、总结与对比表

解法 核心思想 时间复杂度 空间复杂度 适用场景
排序法 哈希 + 排序 O(N log N) O(N) 数据量较小
小顶堆法 哈希 + 最小堆 O(N log K) O(N) 高频前K问题通用
桶排序法 哈希 + 桶分布 O(N) O(N) 频率有限且整数集合适用
相关推荐
凤凰院凶涛QAQ10 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
科技大视界11 小时前
投资AI项目,传统尽调不够用了——李章虎律师拆解算法、数据、算力三大雷区
人工智能·算法·数据挖掘
郝学胜-神的一滴11 小时前
算法实战:最小k个数——大顶堆的优雅解法
开发语言·数据结构·c++·python·程序人生·算法·排序算法
Irissgwe11 小时前
算法滑动窗口
数据结构·算法
怪兽学LLM11 小时前
LeetCode 105. 从前序与中序遍历序列构造二叉树:分治递归思路详解
算法·leetcode·职场和发展
可编程芯片开发11 小时前
基于PI控制的三相整流器控制系统的simulink建模与仿真,包含超级电容充电和电机
算法
酿情师12 小时前
区块链共识算法深度拆解:PoW、PoS、PBFT、Raft 原理解析
算法·区块链·共识算法
hansang_IR12 小时前
【记录】「SCOI2016」三道模拟赛/26.7.12
c++·算法
退休倒计时12 小时前
【每日一题】LeetCode 39. 组合总和 TypeScript
算法·leetcode·typescript
不是az12 小时前
力控相关知识点
算法·机器学习·最小二乘法