代码随想录Day13
LeetCode347 前K个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
- 输入: nums = [1,1,1,2,2,3], k = 2
- 输出: [1,2]
示例 2:
- 输入: nums = [1], k = 1
- 输出: [1]
思路:求前K个高频,这种题目要想到大顶堆和小顶堆(优先级队列)。
- 要统计元素出现频率
- 对频率排序
- 找出前K个高频元素
大顶堆和小顶堆:
堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。
我们要维护前K个高频,那么就要不断地把不需要的值进行取舍,弹出。
堆的弹出是从根节点弹出,所以我们可以采用小顶堆的方式来做。如果不用保持队列是前k的话,还是可以采用大顶堆来完成。
代码:
/*Comparator接口说明: * 返回负数,形参中第一个参数排在前面;返回正数,形参中第二个参数排在前面 * 对于队列:排在前面意味着往队头靠 * 对于堆(使用PriorityQueue实现):从队头到队尾按从小到大排就是最小堆(小顶堆), * 从队头到队尾按从大到小排就是最大堆(大顶堆)--->队头元素相当于堆的根节点 * */ class Solution { //解法1:基于大顶堆实现 public int[] topKFrequent1(int[] nums, int k) { Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数 for(int num:nums){ map.put(num,map.getOrDefault(num,0)+1); } //在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数 //出现次数按从队头到队尾的顺序是从大到小排,出现次数最多的在队头(相当于大顶堆) PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2)->pair2[1]-pair1[1]); for(Map.Entry<Integer,Integer> entry:map.entrySet()){//大顶堆需要对所有元素进行排序 pq.add(new int[]{entry.getKey(),entry.getValue()}); } int[] ans = new int[k]; for(int i=0;i<k;i++){//依次从队头弹出k个,就是出现频率前k高的元素 ans[i] = pq.poll()[0]; } return ans; } //解法2:基于小顶堆实现 public int[] topKFrequent2(int[] nums, int k) { Map<Integer,Integer> map = new HashMap<>();//key为数组元素值,val为对应出现次数 for(int num:nums){ map.put(num,map.getOrDefault(num,0)+1); } //在优先队列中存储二元组(num,cnt),cnt表示元素值num在数组中的出现次数 //出现次数按从队头到队尾的顺序是从小到大排,出现次数最低的在队头(相当于小顶堆) PriorityQueue<int[]> pq = new PriorityQueue<>((pair1,pair2)->pair1[1]-pair2[1]); for(Map.Entry<Integer,Integer> entry:map.entrySet()){//小顶堆只需要维持k个元素有序 if(pq.size()<k){//小顶堆元素个数小于k个时直接加 pq.add(new int[]{entry.getKey(),entry.getValue()}); }else{ if(entry.getValue()>pq.peek()[1]){//当前元素出现次数大于小顶堆的根结点(这k个元素中出现次数最少的那个) pq.poll();//弹出队头(小顶堆的根结点),即把堆里出现次数最少的那个删除,留下的就是出现次数多的了 pq.add(new int[]{entry.getKey(),entry.getValue()}); } } } int[] ans = new int[k]; for(int i=k-1;i>=0;i--){//依次弹出小顶堆,先弹出的是堆的根,出现次数少,后面弹出的出现次数多 ans[i] = pq.poll()[0]; } return ans; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!