LeetCode347. 前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值进行降序排序。


代码

class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        List<Integer> list = new ArrayList<>();
        
        PriorityQueue<Map.Entry<Integer,Integer>> pq = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o2.getValue()-o1.getValue();
            }
        });

        Map<Integer,Integer> map = new HashMap<>();
        
        for (int i = 0; i < nums.length; i++) 
            if (map.containsKey(nums[i]))
                map.put(nums[i],map.get(nums[i])+1);
            else
                map.put(nums[i],1);

        Set<Map.Entry<Integer,Integer>> set = map.entrySet();
        
        for (Map.Entry<Integer,Integer> entry : set)
            pq.add(entry);
        

        for (int i = 0; i < k; i++) 
            list.add(pq.poll().getKey());
        
        return list;
    }
}


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

Map.Entry

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


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值