<堆和优先队列> leetcode 347.数组前K个高频元素

163 阅读1分钟

题目

leetcode.cn/problems/to…

思路

  • 用map统计数组频次
  • 不直接将所有元素入堆,否则复杂度达到O(nlogn)
  • 之前的文章介绍过堆的特点<数据结构>关于堆、优先,即保持堆顶的最值性,寻找前K大的数据可以转换成维护一个大小为K的最小堆。在遍历时,堆满时,大于堆顶的元素抛出堆顶并入堆。这时就将局部最小值转换成全局的第k大的值。

java实现

//前k个高频:
//1. 用map统计频率
//2. 用优先队列维护k的最小堆,当nums[i]大于堆顶则抛出根节点入堆。维护全局的最大K个元素
class Solution {
    Map<Integer,Integer> map = new HashMap<>();
    PriorityQueue<int[]> queue = new PriorityQueue<>((o1, o2) -> o1[1]-o2[1]);
    public int[] topKFrequent(int[] nums, int k) {
        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
        }

        for(Map.Entry<Integer,Integer> entry : map.entrySet()){
            if(queue.size()<k){
                queue.add(new int[]{entry.getKey(), entry.getValue()});
            }
            else{
                if(entry.getValue()>queue.peek()[1]){
                    queue.poll();
                    queue.add(new int[]{entry.getKey(), entry.getValue()});
                }
            }
        }
        int[] ans = new int[k];
        for (int i = 0; i < k; i++) {
            if(!queue.isEmpty()){
                ans[i] = queue.poll()[0];
            }
        }
        return ans;
    }
}