1. 题目
https://leetcode.cn/problems/top-k-frequent-elements/
考察点
这道题的考察点是:
- 如何使用哈希表来统计元素的出现频率。
- 如何使用最小堆来找出前k个高频元素。
- 如何利用堆的性质来优化时间复杂度。
- 如何使用合适的数据结构来存储和返回结果。
2. 解法
思路
Leetcode 347题,这是一个关于找出数组中出现频率最高的k个元素的问题。
有多种方法可以实现这个问题,但是题目要求算法的时间复杂度必须优于O(n log n),其中n是数组的大小。
一种可能的方法是使用哈希表和最小堆。
- 哈希表可以用来存储每个元素出现的次数,
- 然后遍历哈希表,将元素和次数作为一个对放入最小堆中,
- 如果堆的大小超过k,就弹出堆顶元素,这样保证堆中只有出现次数最高的k个元素。
- 最后,将堆中的元素放入一个列表中返回。
这种方法的时间复杂度是O(n log k),空间复杂度是O(n)。
代码逻辑
- 用哈希表记录每个元素的出现次数。
- 我们创建一个哈希表map,用来存储数组中每个元素出现的次数。我们遍历数组中的每个元素num,如果map中已经有num作为键,就将其对应的值加一,否则就将num作为键,1作为值放入map中。这样,map中就记录了数组中每个元素及其出现的次数。
- 用最小堆维护出现次数最高的k个元素。
- 我们创建一个最小堆queue,用来存储元素和次数的对。我们遍历map中的每个键值对entry,将entry的键和值作为一个数组放入queue中。如果queue的大小超过了k,就说明queue中有不属于前k个高频元素的元素,我们就将queue的堆顶元素弹出。这样,queue中就保留了出现次数最高的k个元素及其次数。
- 用列表存储最小堆中的元素。
- 我们创建一个列表list,用来存储最终的结果。我们将queue中的每个元素弹出,并将其第一个元素(即原数组中的元素)放入list中。这样,list中就包含了前k个高频元素。
- 用数组返回列表中的元素。
- 我们创建一个数组res,用来返回结果。我们遍历list中的每个元素,并将其放入res中。这样,res就是一个包含前k个高频元素的数组。
以上就是代码的逻辑概述。
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import java.util.*; class Solution { public int [] topKFrequent( int [] nums, int k) { // 哈希表存储元素和次数 Map<Integer, Integer> map = new HashMap<>(); for ( int num : nums) { map.put(num, map.getOrDefault(num, 0 ) + 1 ); } // 最小堆存储元素和次数的对 PriorityQueue< int []> queue = new PriorityQueue<>((a, b) -> a[ 1 ] - b[ 1 ]); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { queue.offer( new int []{entry.getKey(), entry.getValue()}); if (queue.size() > k) { queue.poll(); } } // 将堆中的元素放入列表中 List<Integer> list = new ArrayList<>(); while (!queue.isEmpty()) { list.add(queue.poll()[ 0 ]); } // 将列表转换为数组并返回 int [] res = new int [k]; for ( int i = 0 ; i < k; i++) { res[i] = list.get(i); } return res; } } |
3. 总结
分类:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)