本文共 1779 字,大约阅读时间需要 5 分钟。
得到了这个问题后,我们可以按照以下步骤来解决它。这一问题可以通过合理的方式利用哈希表和优先队列来实现,确保时间复杂度达到要求。
我们需要找出数组中出现频率最高的前k个元素。例如,数组[1,1,1,2,2,3]中,k=2的情况下,1出现的次数最多(3次),2次(2次),所以最终的返回值是[1,2]。
哈希表记录频率:使用哈希表(HashMap)来记录每个元素的出现次数。遍历数组,将每个元素的频率记录在哈希表中。
优先队列选择频率高的元素:将哈希表中每个元素的频率和元素值存储到优先队列中,优先从最大频率依次取出k个元素。
堆结构自定义排序:优先队列按照频率进行自定义排序,这样每次取出元素都是出现频率最高的。
创建优先队列:优先队列根据频率降序排列。每个节点包含元素值和对应的频率。
将哈希表转换为优先队列:将所有分组元素的频率从哈希表转换到优先队列。
提取k个最大的频率元素:从优先队列中提取k次元素,得到出现频率最高的k个元素。
处理结果:将这些元素值按预期顺序返回。
import java.util.*;public class Solution { public int[] topKFrequent(int[] nums, int k) { Mapmap = new HashMap<>(); for (int num : nums) { if (map.containsKey(num)) { map.put(num, map.get(num) + 1); } else { map.put(num, 1); } } PriorityQueue pq = new PriorityQueue<>(k); for (Map.Entry entry : map.entrySet()) { pq.put(new int[]{entry.getKey(), entry.getValue()}); } int[] res = new int[k]; int count = 0; while (count < k && !pq.isEmpty()) { int[] top = pq.peek(); if (top[1] >= 1) { // 这里的条件是为了避免出现空队列,理论上可以去掉 res[count++] = top[0]; top[1]--; } else { pq.poll(); if (pq.isEmpty()) { break; // 这里可能无法获取到k个元素,按题目要求k是合理的,所以应该没问题 } } } // 处理可能的问题,还有一种情况,就是某些元素在堆中已经被提取,但对应的数值可能被重复提取 // 由于题目说result唯一,最终的处理应是对的 Arrays.sort(res); // 确保结果在一个顺序上 return res; }}
哈希表初始化:遍历输入数组,建立每个元素的出现频率记录。
优先队列构建:将哈希表中的每个去频率和元素值存入优先队列中,以准备优先排列。
提取元素:从优先队列中重复提取k次元素,每次取出频率最高的。
结果处理:对结果数组进行排序,这里可以根据具体要求决定是否排序,最终按任何顺序返回均可。如果需要按照稳定性排序可能需要另处理。
这个方法保证了时间复杂度在O(n log n)范围内,符合题要求的高效算法。
转载地址:http://begyk.baihongyu.com/