leecode347_出现频率前k高的元素_Map+PriorityQueue

347.题目描述

在这里插入图片描述

算法思想一

要想实现输出出现次数最多的前k个数据,那么
1.统计数组中每个元素出现的次数
————通过Map<非重复数据,出现频率>可以很好的实现
2.根据统计次数(频率\value值)进行排序
————先转化为Map.Entry的list,使用Collections.sort()降序排序
3.排序后的list获取前k个Map.Entry(list存map)的Key值
————list.get(i).getKey()

缺点:其性能受都排序算法的影响 nlog(n)

public List<Integer> topKFrequent(int[] nums, int k) {
    List<Integer> list = new ArrayList<Integer>();
    Map<Integer,Integer> map = new HashMap<Integer,Integer>();
    if (nums.length==0) return list;
    for(int num:nums){//遍历数组,获取每个元素出现次数
        if(map.containsKey(num))
            map.put(num,map.get(num)+1);//获取当前key对应的value
        else
            map.put(num,1);
    }
//将map转换为Map.Entry,之后使用compare进行对Value的排序。TreeMap自动对Key进行排序,升序排序。
List<Map.Entry<Integer,Integer>> listmap = new ArrayList<Map.Entry<Integer,Integer>>(map.entrySet());//map转换为list
Collections.sort(listmap,new Comparator<Map.Entry<Integer,Integer>>(){         //通过比较器排序,注意比较器写法
    public int compare(Map.Entry<Integer,Integer> num1,Map.Entry<Integer,Integer> nums2){
        return nums2.getValue()-num1.getValue();//降序排序
    }
});
for(int i = 0 ;i<k;i++){
    list.add(listmap.get(i).getKey());
}
return list;
}

提交记录

     执行用时:19 ms
     内存消耗:42.7 MB

算法思想二

优先队列,先进先出并且java中默认为最小堆实现。队列第一个元素是最小值。考虑将排序好的map,根据元素出现频率存入长度为k的queue,若当前频率>队列中频率最小频率,则的出队列。此时,排序算法只需要对queue的k个值进行,其算法复杂度可提升为nlog(k)
1.统计数组中每个元素出现的次数
————通过Map<非重复数据,出现频率>可以很好的实现
2.实例化PriorityQueue
————为后期获取num容易,存入Pair<数据,频率>
3.循环map
————如果队列长度小于k,入队列
————如果队列长度大于k
——————判断当前元素频率与队列头peek关系,若小于则不处理,若大于则将当前队列头出队列后将当前判断元素存入
4.将队列中数据存入list中返回
————注:PriorityQueue中存的Pair,foreach的时候接收对象为Pair

public List<Integer> topKFrequent(int[] nums, int k) {
    List<Integer> list = new ArrayList<Integer>();
    Map<Integer,Integer> map = new HashMap<Integer,Integer>();
    if (nums.length==0) return list;
    for(int num:nums){
        if(map.containsKey(num))
            map.put(num,map.get(num)+1);//获取当前key对应的value
        else
            map.put(num,1);
    }
    //队列存满足的k个数,按照 次数进行从小到大排列
    PriorityQueue<Pair<Integer,Integer>> pq = new PriorityQueue<Pair<Integer,Integer>>(new Comparator<Pair<Integer, Integer>>() {
        @Override
        public int compare(Pair<Integer, Integer> integerIntegerPair, Pair<Integer, Integer> t1) {
            return integerIntegerPair.getValue()-t1.getValue();
        }
    });//默认从小到大排序
    for(Map.Entry<Integer,Integer> me:map.entrySet()){
        if(pq.size()==k ){
            if(me.getValue()>pq.peek().getValue()) {
                pq.poll();
                pq.offer(new Pair(me.getKey(), me.getValue()));
            }
        }else{
            pq.offer(new Pair(me.getKey(),me.getValue()));
        }
    }
    for(Pair<Integer,Integer> num : pq){
        list.add(num.getKey());
    }
    return list;
}

提交记录

    执行用时:17 ms
    内存消耗:42.9 MB
发布了16 篇原创文章 · 获赞 0 · 访问量 557

猜你喜欢

转载自blog.csdn.net/sunlili_yt/article/details/105279654