347.题目描述
算法思想一
要想实现输出出现次数最多的前k个数据,那么
1.统计数组中每个元素出现的次数
————通过Map<非重复数据,出现频率>可以很好的实现
2.根据统计次数(频率\value值)进行排序
————先转化为Map.Entry的list,使用Collections.sort()降序排序
3.排序后的list获取前k个Map.Entry(list存map)的Key值
————list.get(i).getKey()
缺点:其性能受都排序算法的影响 nlog(n)
public List<Integer> topKFrequent(int[] nums, int k) {
List<Integer> list = new ArrayList<Integer>();
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
if (nums.length==0) return list;
for(int num:nums){//遍历数组,获取每个元素出现次数
if(map.containsKey(num))
map.put(num,map.get(num)+1);//获取当前key对应的value
else
map.put(num,1);
}
//将map转换为Map.Entry,之后使用compare进行对Value的排序。TreeMap自动对Key进行排序,升序排序。
List<Map.Entry<Integer,Integer>> listmap = new ArrayList<Map.Entry<Integer,Integer>>(map.entrySet());//map转换为list
Collections.sort(listmap,new Comparator<Map.Entry<Integer,Integer>>(){ //通过比较器排序,注意比较器写法
public int compare(Map.Entry<Integer,Integer> num1,Map.Entry<Integer,Integer> nums2){
return nums2.getValue()-num1.getValue();//降序排序
}
});
for(int i = 0 ;i<k;i++){
list.add(listmap.get(i).getKey());
}
return list;
}
提交记录
执行用时:19 ms
内存消耗:42.7 MB
算法思想二
优先队列,先进先出并且java中默认为最小堆实现。队列第一个元素是最小值。考虑将排序好的map,根据元素出现频率存入长度为k的queue,若当前频率>队列中频率最小频率,则的出队列。此时,排序算法只需要对queue的k个值进行,其算法复杂度可提升为nlog(k)。
1.统计数组中每个元素出现的次数
————通过Map<非重复数据,出现频率>可以很好的实现
2.实例化PriorityQueue
————为后期获取num容易,存入Pair<数据,频率>
3.循环map
————如果队列长度小于k,入队列
————如果队列长度大于k
——————判断当前元素频率与队列头peek关系,若小于则不处理,若大于则将当前队列头出队列后将当前判断元素存入
4.将队列中数据存入list中返回
————注:PriorityQueue中存的Pair,foreach的时候接收对象为Pair
public List<Integer> topKFrequent(int[] nums, int k) {
List<Integer> list = new ArrayList<Integer>();
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
if (nums.length==0) return list;
for(int num:nums){
if(map.containsKey(num))
map.put(num,map.get(num)+1);//获取当前key对应的value
else
map.put(num,1);
}
//队列存满足的k个数,按照 次数进行从小到大排列
PriorityQueue<Pair<Integer,Integer>> pq = new PriorityQueue<Pair<Integer,Integer>>(new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> integerIntegerPair, Pair<Integer, Integer> t1) {
return integerIntegerPair.getValue()-t1.getValue();
}
});//默认从小到大排序
for(Map.Entry<Integer,Integer> me:map.entrySet()){
if(pq.size()==k ){
if(me.getValue()>pq.peek().getValue()) {
pq.poll();
pq.offer(new Pair(me.getKey(), me.getValue()));
}
}else{
pq.offer(new Pair(me.getKey(),me.getValue()));
}
}
for(Pair<Integer,Integer> num : pq){
list.add(num.getKey());
}
return list;
}
提交记录
执行用时:17 ms
内存消耗:42.9 MB