【LeetCode-中等题】347. 前 K 个高频元素

题目

在这里插入图片描述

方法一:优先队列(基于大顶堆实现)

PriorityQueue<int[]> queue = new PriorityQueue<>((a,b)->b[1]-a[1]);
优先队列 按照队列中的数组的第二个元素从大到小排序
((a,b)->b[1]-a[1])
在这里插入图片描述

class Solution {
    
    
    //基于大顶堆实现
    public int[] topKFrequent(int[] nums, int k) {
    
    
        Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数
        //在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数
        //出现次数按从队头到队尾的顺序是从大到小排,出现次数最多的在队头(相当于大顶堆)
        PriorityQueue<int[]> queue = new PriorityQueue<>((a,b)->b[1]-a[1]);

        for(int num : nums)
            map.put(num,map.getOrDefault(num,0)+1);

        //将map集合中的  key(num)  value(出现次数)  以数组的形式  a[key  ,  value]  加入到优选队列中  
        ///按照value从大到小的顺序进行排列
        for(Map.Entry<Integer,Integer> entry :map.entrySet())
            queue.add(new int[]{
    
    entry.getKey(),entry.getValue()});
        
        //取出优先队列(已经按照value按从大到小排序好了)排在前k位的(key)到结果数组
        int[] res = new int[k];
        for(int i = 0 ; i < k ; i++){
    
    
            res[i] = queue.poll()[0];
        }
        return res;
    }
}

方法二:优先队列(基于小顶堆实现,队列只需维护k个元素)

PriorityQueue<int[]> queue = new PriorityQueue<>((a,b)->a[1]-b[1]);
优先队列 按照队列中的数组的第二个元素从小到大排序
((a,b)->a[1]-b[1])
在这里插入图片描述

class Solution {
    
    
    //基于小顶堆实现
    public int[] topKFrequent(int[] nums, int k) {
    
    
        Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数
        //在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数
        //出现次数按从队头到队尾的顺序是从小到大排,出现次数最多的在队头(相当于大顶堆)
        PriorityQueue<int[]> queue = new PriorityQueue<>((a,b)->a[1]-b[1]);

        for(int num : nums)
            map.put(num,map.getOrDefault(num,0)+1);

        //将map集合中的  key(num)  value(出现次数)  以数组的形式  a[key  ,  value]  加入到优选队列中  
        ///按照value从大到小的顺序进行排列
        for(Map.Entry<Integer,Integer> entry :map.entrySet()){
    
    //小顶堆只需要维持k个元素有序
        //如果队列大小小于k  直接将 a[key  ,  value]加入队列
                if(queue.size() < k)  queue.offer(new int[]{
    
    entry.getKey(),entry.getValue()});
        //如果队列大小为k  则需要判断当前对列队首的数组  value(次数) 和 entry.getValue()对比  如果大于队首的value  则替换队首元素,否则不做改变
                else if(entry.getValue() > queue.peek()[1]){
    
     
                        queue.poll();
                        queue.offer(new int[]{
    
    entry.getKey(),entry.getValue()});
                }
        }

        int[] res = new int[k];
          //由于优先队列时小根堆,所以出现次数大的出现在队列对后面  需要逆序把队列中的key 放到结果数组中
        for(int i = k-1 ; i >=0 ; i--)
            res[i] = queue.poll()[0];
        
        return res;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45618869/article/details/132997915