给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
思路:
先用map统计,在用最小堆获得频率前k高的元素。
本文主要是为了记录Pair<>,自定义比较器Comparator<>等的使用。
使用自定义类Freq,实现Comparable接口(重写compareTo方法)
public class Solution {
private class Freq implements Comparable<Freq> {
int e, freq;
public Freq(int e, int freq) {
this.e = e;
this.freq = freq;
}
@Override
public int compareTo(Freq o) {
return this.freq - o.freq;
}
}
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
//默认最小堆
PriorityQueue<Freq> pq = new PriorityQueue<>();
for (int key : map.keySet()) {
if (pq.size() < k)
pq.add(new Freq(key, map.get(key)));
else if (map.get(key) > pq.peek().freq) {
pq.poll();
pq.add(new Freq(key, map.get(key)));
}
}
LinkedList<Integer> res = new LinkedList<>();
while (!pq.isEmpty()) {
res.add(pq.poll().e);
}
return res;
}
}
使用自定义类Freq,再定义一个比较器类FreqComparator实现Comparator接口
public class Solution {
private class Freq {
int e, freq;
public Freq(int e, int freq) {
this.e = e;
this.freq = freq;
}
}
private class FreqComparator implements Comparator<Freq>{
@Override
public int compare(Freq o1, Freq o2) {
return o1.freq-o2.freq;
}
}
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
//最小堆
PriorityQueue<Freq> pq = new PriorityQueue<>(new FreqComparator());
for (int key : map.keySet()) {
if (pq.size() < k)
pq.add(new Freq(key, map.get(key)));
else if (map.get(key) > pq.peek().freq) {
pq.poll();
pq.add(new Freq(key, map.get(key)));
}
}
LinkedList<Integer> res = new LinkedList<>();
while (!pq.isEmpty()) {
res.add(pq.poll().e);
}
return res;
}
}
使用自定义类Freq,使用匿名内部类
//最小堆
//匿名内部类
PriorityQueue<Freq> pq = new PriorityQueue<>(new Comparator<Freq>() {
@Override
public int compare(Freq o1, Freq o2) {
return o1.freq-o2.freq;
}
});
//lambda表达式
PriorityQueue<Freq> pq = new PriorityQueue<>(((o1, o2) -> o1.freq-o2.freq));
不使用自定义类,在PriorityQueue只存Integer
public class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
//重新定义整型的比较
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return map.get(o1)-map.get(o2); //在此匿名类中能拿到算法中所有变量
}
});
for (int key : map.keySet()) {
if (pq.size() < k)
pq.add(key);
else if (map.get(key) > map.get(pq.peek())) {
pq.poll();
pq.add(key);
}
}
LinkedList<Integer> res = new LinkedList<>();
while (!pq.isEmpty()) {
res.add(pq.poll());
}
return res;
}
}
使用Pair<K,V> 代替自定义类
public class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
//最小堆
PriorityQueue<Pair<Integer,Integer>> pq = new PriorityQueue<>(((o1, o2) -> o1.getValue()-o2.getValue()));
for (int key : map.keySet()) {
if (pq.size() < k)
pq.add(new Pair<>(key, map.get(key)));
else if (map.get(key) > pq.peek().getValue()) {
pq.poll();
pq.add(new Pair<>(key, map.get(key)));
}
}
LinkedList<Integer> res = new LinkedList<>();
while (!pq.isEmpty()) {
res.add(pq.poll().getKey());
}
return res;
}
}