LeetCode347:返回频率前K高的元素
package com.lt.datastructure.MaxHeap; import java.util.LinkedList; import java.util.List; import java.util.TreeMap; import com.lt.datastructure.Queue.PriorityQueue; /** LeetCode347 给定一个非空的整数数组,返回其中出现频率前 k 高的元素。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 说明: 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。 频次: 用map 复杂度优于O(nlogn):优先队列 频次越低,优先于越高 1 TreeMap存储,键存数组的值,值存数组的值频次 2 新建Freq类,成员属性是e,freq,实现Comparable,重写CompareTo,相反地,频次小的优先级高,返回1 3 优先队列存储Freq,遍历map,如果没存满k个,继续入队,如果存满了,将队首元素和新元素的频次比较,优先级高的(频次低)出队 4 用LinkedList存储优先队列中的元素,作为结果输出 */ public class Solution{ private class Freq implements Comparable<Freq>{ public int e,freq; public Freq(int e, int freq) { this.e = e; this.freq = freq; } @Override public int compareTo(Freq another) { if(this.freq < another.freq){ return 1; }else if(this.freq > another.freq){ return -1; }else{ return 0; } } } public List<Integer> 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); } } //优先队列存储前k个频次最高的元素 PriorityQueue<Freq> pq = new PriorityQueue<>(); for(int key : map.keySet()){ //没存满,继续存 if(pq.getSize()<k){ pq.enqueue(new Freq(key,map.get(key))); //存满了,比较次数,次数低的优先级高,出队,频次高的入队 }else if(map.get(key)>pq.getFront().freq){ pq.dequeue(); pq.enqueue(new Freq(key,map.get(key))); } } //将优先队列的元素存于链表并作为结果输出 LinkedList<Integer> res = new LinkedList<>(); while(!pq.isEmpty()){ res.add(pq.dequeue().e); } return res; } }
import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.PriorityQueue; import java.util.TreeMap; public class Solution { private class Freq implements Comparable<Freq>{ //元素,频次 public int e,freq; public Freq(int e , int freq) { this.e = e; this.freq = freq; } @Override public int compareTo(Freq another) { if(this.freq < another.freq){ return -1; } else if(this.freq > another.freq){ return 1; }else{ return 0; } } } public List<Integer> topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new TreeMap<>(); for (int i : nums) { if(map.containsKey(i)){ map.put(i, map.get(i) + 1); }else{ map.put(i, 0); } } //最小堆,频次最高的优先出队 PriorityQueue<Freq> queue = new PriorityQueue<>(); for(int key : map.keySet()){ if(queue.size() < k){ queue.add(new Freq(key, map.get(key))); } else if(map.get(key) > queue.peek().freq){ queue.remove(); queue.add(new Freq(key, map.get(key))); } } LinkedList<Integer> res = new LinkedList<>(); while(!queue.isEmpty()){ res.add(queue.remove().e); } return res; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端