获取N个元素中的前K个高频元素
题目描述:
给定一个非空的整数数组,返回其中出现频率前K高的元素
示例1:
输入:nums=[1,1,1,2,2,3],k=2
输出:[1,2]
示例2:
输入:nums=[1],k=1
输出:[1]
说明:
1.你可以假设给定的K总是合理的,且1<=k<=数组中不相同的元素个数
2.你的算法时间复杂度必须优于O(nlogn),n是数组的大小。
题目思路:
1.遍历元素集,将具体的key值与其出现频率保存Map中;
2.使用优先级队列(最大堆)存储出现频率最高的前k个键值对;
3.使用List存储优先队列中的所有key
实现方法:
双层循环
最大堆
最小堆
桶排序
1.双层循环(时间复杂度不满足题目要求,但也可以实现)
package heapTask;
import java.util.*;
/**
* 双层循环实现
* 时间复杂度:O(nlogn),其中n表示数组长度
* 空间复杂度:O(n),最极端情况下(每个元素都不同),用于存储元素及其频率的Map需要存储n个键值对
*/
public class Solution2 {
public List<Integer> topKFrequent(Integer[] nums,int k){
//第一步:统计元素频率存入map中
Map<Integer,Integer> map=new HashMap<>();
for(int i:nums){
//若当前元素频率为空,说明当前元素为第一次出现,故频率设置为1
if(map.get(i)==null)
map.put(i,1);
else{
//若当前元素非第一次出现,则出现频率在之前的基础上加1
map.put(i,map.get(i)+1);
}
}
//对元素按照频率进行降序排序
List<Map.Entry<Integer,Integer>> list=new ArrayList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
return o2.getValue()-o1.getValue();
}
});
//取出前K个元素
int count=0;
List<Integer> list1=new ArrayList<>();
for(Map.Entry<Integer,Integer> entry:list){
list1.add(entry.getKey());
++count;
if(count>=k)
break;
}
return list1;
}
public static void main(String[] args) {
Integer[] nums=new Integer[]{
1,1,1,2,2,3};
List<Integer> list=new Solution2().topKFrequent(nums,2);
System.out.println(list);
}
}
//[1,2]
最大堆—自定义优先级队列
因优先级队列是基于堆实现的,故需首先创建最大堆实现基本功能(增加元素、取出元素等),之后自定义优先级队列依赖堆实现基本功能(入队、出队、堆顶元素、是否为空、堆中元素个数),最后根据该题三步解题思路做出该题。
//Heap.java
package heap;
import java.util.Arrays;
import java.util.Comparator;
//基于数组实现的二叉堆
public class Heap<E> {
//实现任意类的大小比较
private Comparator<E> comparator;
private int size;
private E[] elementData;
//默认初始容量
private static final int DEFAULT_CAPACITY=10;
public Heap() {
this(null,DEFAULT_CAPACITY);
}
public Heap(int initialCapacity) {
this(null,initialCapacity);
}
public Heap(Comparator<E> comparator, int initialCapacity) {
this.elementData= (E[]) new Object[initialCapacity];
this.comparator=comparator;
}
public Heap(E[] arr){
elementData=