栈与队列系列⑤ -- 前k个高频元素

举报
十八岁讨厌编程 发表于 2022/08/06 00:17:35 2022/08/06
【摘要】 目录 题目概述做题思路两个注意点优先级队列的排序问题Comparator接口的实现 代码实现代码中的注意点Java HashMap getOrDefault() 方法lambda表达式 ...

题目概述

此题对应力扣的347.前k个高频元素
题目:

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

示例:

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

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

做题思路

此题使用两种结构:

  • map字典计数
  • 优先级队列排序

为什么使用优先级队列排序,而不是用列表等其他结构?
因为为了保证程序效率,其实我们只用关注前k个元素即可,不用对整个进行排序,而队列可以很好地满足这一点。
如此下来思路就很简单了,具体的做法就是:将数组中的数据用字典计数之后,转化为EntrySet,再将键对值放入优先级队列中,在加的时候同时控制队列的总数不超过k,超过k的弹出去,最后将队列中的元素放入数组中返回即可。

两个注意点

优先级队列的排序问题

因为我们要让前k个最大的留在队列里,所以这个队列要从小到大排序(注意在java的PriorityQueue中最小的元素是排在队头的),满足最小的在队头,最大的在队尾,如此往外弹出溢出k的元素时,才不会把最大的元素弹出去。

Comparator接口的实现

在我们创建优先级队列的时候,因为我们是对Entry的值进行排序,所以我们传入我们自己重写的实现了 Comparator接口的实例,如此才能达到我们的目的。

代码实现

public int[] topKFrequent(int[] nums, int k) {
        //创建一个优先级队列
        Queue<Map.Entry<Integer,Integer>> queue = new PriorityQueue<>((a1,a2) -> a1.getValue() - a2.getValue());
        //创建一个字典计数
        Map<Integer,Integer> map  = new HashMap<>();
        // 开始对数组中的元素计数
        for(int num : nums){
            map.put(num,map.getOrDefault(num,0) + 1);
        }
        // 将键值对放入Set中
        Set<Map.Entry<Integer,Integer>> box = map.entrySet();
        // 将键值对放入优先级队列中(本质小根堆)
        for(Map.Entry<Integer,Integer> entry:box){
            queue.add(entry);
            //只要超过k就把队头的较小值给弹出去
            while (queue.size() > k){
                queue.poll();
            }
        }
        //将队列中的元素拿出来放在数组中返回
        int[] ans = new int[k];
        for(int i = 0;i < k;i++){
            ans[i] = queue.poll().getKey();
        }
        return ans;
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

代码中的注意点

Java HashMap getOrDefault() 方法

getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。

getOrDefault() 方法的语法为:

hashmap.getOrDefault(Object key, V defaultValue)

参数说明:

  • key - 键
  • defaultValue - 当指定的key并不存在映射关系中,则返回的该默认值

返回值:
返回 key 相映射的的 value,如果给定的 key 在映射关系中找不到,则返回指定的默认值。

lambda表达式

在代码中有一个地方:

Queue<Map.Entry<Integer,Integer>> queue = new PriorityQueue<>((a1,a2) -> a1.getValue() - a2.getValue());

我们在传入Comparator接口的实现类的实例时,可以使用lambda表达式,如此可以使代码更加简洁。

文章来源: blog.csdn.net,作者:十八岁讨厌编程,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/zyb18507175502/article/details/122381282

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。