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

文章目录

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

题目

【LeetCode-中等题】347. 前 K 个高频元素_第1张图片

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

PriorityQueue queue = new PriorityQueue<>((a,b)->b[1]-a[1]);
优先队列 按照队列中的数组的第二个元素从大到小排序
((a,b)->b[1]-a[1])
【LeetCode-中等题】347. 前 K 个高频元素_第2张图片

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 queue = new PriorityQueue<>((a,b)->a[1]-b[1]);
优先队列 按照队列中的数组的第二个元素从小到大排序
((a,b)->a[1]-b[1])
【LeetCode-中等题】347. 前 K 个高频元素_第3张图片

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;
    }
}

你可能感兴趣的:(力扣,#,中等题,leetcode,算法,职场和发展)