首页 > 其他 > 详细

LeetCode347. 前 K 个高频元素

时间:2020-05-06 00:29:59      阅读:91      评论:0      收藏:0      [点我收藏+]

题目描述:

技术分享图片

 

 

 

 题解分析(见课程8-7和8-8):首先求出所有元素的频次(映射Map),然后利用频次求出前k高的元素(优先队列)。具体来说,问题转化为“在N个元素中选出前M个元素,M<<N”,最朴素的想法是采用排序,但使用快排等高级排序算法,复杂度在NlogN;更好的方法是采用优先队列,复杂度在NlogM,其思路是使用优先队列,维护当前看到的前M个元素,不断将前M大元素中最小的元素进行替换,因此需要使用最小堆。那么最小堆如何实现呢?

——对最大堆底层实现进行修改,即最大堆核心逻辑比较时符号需要改变。

——仍然采用最大堆,不一定值越大优先级越高,自己定义元素的值越小,优先级越高即可。 

队首的元素就是优先队列优先级最高的元素,因此,在自定义优先级下,频次最低的元素优先级最高。如果新遍历的key 的频次比当前前k高频次中频次最小的元素要搞,那么就将有限队列中队首的元素出队,然后进队一个新的元素。该算法的复杂度是NlogK。这是利用自己定义的优先队列,内部是一个最大堆。

用Java标准库中的优先队列PriorityQueue,内部默认是一个最小堆。如果想要改变Java标准库中的类相应的比较方式,解决方案是定义一个新的类(比较器,自定义在优先队列中优先级的比较方式),它实现的是Comparator这个接口,在优先队列构造时,让这个比较器作为优先队列的一个参数,比较器定义了在优先队列中如何决定谁的优先级大。

再进一步,不需要专门为PriorityQueue设置一个类,将一个只用一次的类的声明写成匿名类,即传的参数设为一个匿名类,然后把compare的逻辑写出来即可。

更进一步,匿名类具有变量捕获的能力,匿名类中能拿到算法中声明的所有不可改变的变量,利用匿名类改变Java内置类型之间比较的逻辑。

还能进一步化简,从Java8开始,匿名类可以直接使用lamda表达式。

技术分享图片
import java.util.LinkedList;
import java.util.TreeMap;
import java.util.PriorityQueue;
import java.util.Comparator;

class Solution {
    public int[] topKFrequent(int[] nums, int k) {

        TreeMap<Integer, Integer> map = new TreeMap<>();
        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<>(
            (a,b) -> map.get(a) - map.get(b)    // Java8下,匿名类直接使用lamda表达式
        );
        for(int key: map.keySet()){
            if(pq.size()<k){
                pq.add(key);
            }else if (map.get(key) > map.get(pq.peek())){
                pq.remove();
                pq.add(key);
            }
        }

        LinkedList<Integer> res = new LinkedList<>();
        while(!pq.isEmpty()){
            res.add(pq.remove());
        }
        int[] arr= new int[res.size()];
        for(int i = 0; i<res.size(); i++){
            arr[i] = res.get(i);         // LinkedList转换为原始int数组
        }
        return arr;
    }
}
Solution 1

 

LeetCode347. 前 K 个高频元素

原文:https://www.cnblogs.com/HuangYJ/p/12833729.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!