当前位置:   article > 正文

LeetCode347. 前K个高频元素_给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

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

今天继续哈,写的还是比较简单的一个题,哈希表和堆排序,要多多熟悉java的数据结构。


题目

给定一个非空的整数数组,返回其中出现频率前 高的元素。

例如,

给定数组 [1,1,1,2,2,3] , 和 k = 2,返回 [1,2]

注意:

  • 你可以假设给定的 总是合理的,1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 O(n log n) , 是数组的大小。

分析

看到给出一个数组,输出频率最高的第一反应就是哈希表嘛, 因为输出频率前k高的元素,所以要进行一次排序,注意里要求,时间复杂度必须优于O(n log n),堆排序是时间复杂度为O(n log n),这样就用了优先队列PriorityQueue。

首先遍历数组,将数组中的数字和出现的对应频率存入map中,这里可以把map中的键值对分散为一个一个的Map.Entry<K,V>,对value排序存放入堆中,最后将前k大的出队。

java的优先队列默认为小顶堆,在创建堆的时候要写一下比较器,通过entry的value值进行降序排序。


代码

  1. class Solution {
  2. public List<Integer> topKFrequent(int[] nums, int k) {
  3. List<Integer> list = new ArrayList<>();
  4. PriorityQueue<Map.Entry<Integer,Integer>> pq = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
  5. @Override
  6. public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
  7. return o2.getValue()-o1.getValue();
  8. }
  9. });
  10. Map<Integer,Integer> map = new HashMap<>();
  11. for (int i = 0; i < nums.length; i++)
  12. if (map.containsKey(nums[i]))
  13. map.put(nums[i],map.get(nums[i])+1);
  14. else
  15. map.put(nums[i],1);
  16. Set<Map.Entry<Integer,Integer>> set = map.entrySet();
  17. for (Map.Entry<Integer,Integer> entry : set)
  18. pq.add(entry);
  19. for (int i = 0; i < k; i++)
  20. list.add(pq.poll().getKey());
  21. return list;
  22. }
  23. }


因为一开始没有注意到Map.Entry这个的存在,想要在优先队列中存放键值对可是不知道使用什么数据结构,之后看了结题报告才明白,所以要好好熟悉数据结构。

Map.Entry

映射项(键-值对)。Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类。获得映射项引用的唯一 方法是通过此 collection 视图的迭代器来实现。这些 Map.Entry 对象 在迭代期间有效;更确切地讲,如果在迭代器返回项之后修改了底层映射,则某些映射项的行为是不确定的,除了通过 setValue 在映射项上执行操作之外。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/685266
推荐阅读
相关标签
  

闽ICP备14008679号