【Vigor】leetcode刷题 -- 347. 前 K 个高频元素(java)

题目:

【Vigor】leetcode刷题 -- 347. 前 K 个高频元素(java)_第1张图片

题意理解:

  • 依据题意,可知是给定一个数组,且给定一个数值 k ,要求数组中重复元素最多的前 k 个元素。

解题思路:

  • 最开始的想法很粗暴:遍历数组,且创建一个map集合,键来存储数组元素,值则存储对应键出现的频率。最后通过每遍历一次map集合来求出一个中中最大值,同时删去该键
  • 这种想法确实简单粗暴,但是这样的做法因为多次遍历map集合来取得最大值,他的算法时间复杂度肯定远大于 n*n 。而且看了看后面的提示:**你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。**所以,马上打消了这个念头。
  • 既然问题出在了多次遍历 map 集合来求得最大值,那有什么另外的方法可以改进呢?
  • 改变数据结构? -----> 优先队列 PriorityQueue
  • PriorityQueue 是基于二叉堆原理的优先队列,队列用动态数组实现。而二叉堆有如下三个特点:
    1.完全二叉树堆的根节点的优先级最大(即最大或最小)
    2.父节点的优先级必定大于子节点
    3.兄弟节点的优先级不确定谁大谁小
  • 而二叉堆的用途也就是得出最值。优先队列 PriorityQueue 内置属性:Comparator实现优先队列排序的方法。
PriorityQueue<Integer> PQ = new PriorityQueue<>(new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;  //o1 - o2 实现小顶堆(默认)
    }
});
PriorityQueue<Integer> PQ2 = new PriorityQueue<>(new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;  //o2 - o1 实现大顶堆(默认)
    }
});
  • 根据上面的分析,我们用排序的角度来确认优先队列的优势,第一个暴力想法是每次从中取出一个最大值,类似与选择排序,而优先队列采用的是堆的思想,所以类似于堆排序
排序算法 平均时间复杂度
选择排序 O(N*N)
堆排序 O(NlogN)

代码:

public int[] topKFrequent(int[] nums, int k) {
    Map<Integer,Integer> map = new HashMap<>();
    for(int num : nums){
        if(map.containsKey(num)){
            map.put(num,map.get(num)+1);
        }else{
            map.put(num,1);
        }
    }
    PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return map.get(o1) - map.get(o2);  //o1 - o2 实现小顶堆(默认)
        }
    });

    for(Integer key : map.keySet()){
        if(pq.size() < k){
            pq.add(key);
        }else if(map.get(key) > map.get(pq.peek())){
            pq.poll();
            pq.add(key);
        }
    }

    int[] res = new int[k];
    int i = 0;
    while(!pq.isEmpty()){
        res[i] = pq.poll();
        i++;
    }
    return res;
}

执行结果:

【Vigor】leetcode刷题 -- 347. 前 K 个高频元素(java)_第2张图片

你可能感兴趣的:(算法面试题,算法,数据结构,java,堆排序,队列)