[力扣] 347. 前 K 个高频元素 小记

题目

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例1

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

示例2

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

提示:

  • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
  • 你可以按任意顺序返回答案。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/top-k-frequent-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

初始思路

统计每个数出现多少次,第一时间想到数组,但是本题中的元素类型是整数型,与小写字母只有26位不同,在每个测试用例中出现数字的种类数可能不同,因此需要考虑其他的数据结构。
我们可以用哈希表去表示这样的关系:
** Key 值为 出现过的 整形数字, value 值为 整型数字出现的次数 。**
那么接下来的问题是,所有数字统计完毕后,如何根据 value 获取前k次多的数字呢?
这里采用最小堆的做法:即使用 优先队列
每次取最小堆的根部的那个数值(出现次数最多的整数)。

疑点 及 解决方法

  1. 优先队列PriorityQueue 方法实现:

    • peek()//返回队首元素
    • poll()//返回队首元素,队首元素出队列
    • add()//添加元素
    • size()//返回队列元素个数
    • isEmpty()//判断队列是否为空,为空返回true,不空返回false
  2. 比较器排序的写法?(挖了个坑,等自己填)

  3. 如何遍历HashMap?
    for (Map.Entry entry : map.entrySet())

  4. 如何将List转化为Int[ ]?

	// List 转 int[]
    int[] arr1 = list1.stream().mapToInt(Integer::valueOf).toArray();
    // 想要转换成int[]类型,得先转成IntStream,IntStream中默认toArray()转成int[]。
    // 此处通过mapToInt()把Stream调用Integer::valueOf来转成IntStream。

4题引用了的 Kuzma0000 博客 【新手向】Java中List, Integer[], int[]的相互转换

参考代码

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        int len = nums.length;
        Map<Integer,Integer> countMap = new HashMap<Integer,Integer>();//countMap 用于记录某数字 与 其出现次数
            countMap.put(nums[i], countMap.getOrDefault(nums[i], 0) + 1);
        }
        Queue<Map.Entry<Integer,Integer>> queue = new PriorityQueue<>(new Comparator<Map.Entry<Integer,Integer>>(){//重写比较器,比较器的定义是什么?
            @Override
            public int compare(Map.Entry<Integer,Integer> n1,Map.Entry<Integer,Integer> n2){
                return n2.getValue().compareTo(n1.getValue());
            }
        });
        for (Map.Entry<Integer,Integer> entry : countMap.entrySet()) {
            queue.add(entry);
        }
        List<Integer> ans = new ArrayList<Integer>();
        for (int i = 0; i < k; i++) {
            ans.add(queue.poll().getKey());
        }
        // return ans.toArray();//直接转化:转化为一个对象数组,我们需要Int数组
        return ans.stream().mapToInt(Integer::valueOf).toArray();
    }
}

你可能感兴趣的:(力扣,leetcode,java,堆排序,数据结构,算法)