【算法训练】LeetCode#347 前 K 个高频元素

一、描述

347. 前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2:

输入: nums = [1], k = 1
输出: [1]

二、思路

额,如果只是想做出来,那这道题可以是“简单”难度,而不是中等难度,直接遍历计数即可。

  • v1:通过一次遍历得到所有元素出现次数,再利用大顶堆做排序,然后输出前k个。
  • v2:相较于v1,在得到出现次数后,构建一个小顶堆,当需要插入的时候再插入,提升性能。

三、解题


public class LeetCode347 {

    public int[] topKFrequentV1(int[] nums,int k){
        HashMap<Integer,Integer> map = new HashMap<>();
        int[] ans = new int[k];
        for (int val : nums){
            map.put(val,map.getOrDefault(val,0)+1);
        }
        // 大根堆
        PriorityQueue<Map.Entry<Integer, Integer>> queue = 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();
            }
        });
        queue.addAll(map.entrySet());

         while (!queue.isEmpty() && k > 0){
            ans[--k] = queue.poll().getKey();
        }
        return ans;
    }

    public int[] topKFrequentV2(int[] nums,int k){
        HashMap<Integer,Integer> map = new HashMap<>();
        for (int val : nums){
            map.put(val,map.getOrDefault(val,0)+1);
        }
        // 小根堆,用int[]代替键值对,[0]key,[1]val
        PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[1] - o2[1];
            }
        });
        for (Map.Entry<Integer,Integer> entry : map.entrySet()){
            int key = entry.getKey() , val = entry.getValue();
            if (queue.size() == k){
                // 如果堆中已有k个元素,则比较堆顶元素与当前val的大小
                if (queue.peek()[1] < val){
                    // 表明堆顶元素需要淘汰
                    queue.poll();
                    queue.offer(new int[]{key,val});
                }
            } else {
                queue.offer(new int[]{key,val});
            }
        }

        int[] ans = new int[k];
        for (int i = 0 ; i < k ; ++i){
            ans[i] = queue.poll()[0];
        }
        return ans;
    }
}
posted @ 2023-02-11 14:05  小拳头呀  阅读(10)  评论(0编辑  收藏  举报