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;
}
}