题目要求:求前K个最频繁出现的数字。

1.很容易想到,使用HashMap<Integer,Integer>来存储<number,frequency>键值对

1         int n = nums.length;
2 Map<Integer, Integer> map = new HashMap<>(n);
3
4 for (int num : nums) {
5 map.put(num, map.getOrDefault(num, 0) + 1);
6 }

2.接下来非常自然的思路就是:

  • 对<number,frequency>按照frequency进行降序排序
  • 返回前k个<number,frequency>的number

  根据题目的黑字提示:“你可以按 任意顺序 返回答案。”。可以计算出第K频繁的数的frequency,接着遍历map,返回所有frequency >= Kth的number即可:

 1         Integer[] temp = map.values().toArray(new Integer[map.size()]);
2 Arrays.sort(temp);
3 int[] ans = new int[k];
4 int KthCount = temp[temp.length - k], i = 0;
5
6 for (Map.Entry<Integer, Integer> kv : map.entrySet()) {
7 if (kv.getValue() >= KthCount) {
8 ans[i++] = kv.getKey();
9 }
10 }

因为时间超过5%,想到了对map遍历时是否可以直接遍历map中的键值对,于是:

1         for (Map.Entry<Integer, Integer> kv : map.entrySet()) {
2 if (kv.getValue() >= KthCount) {
3 ans[i++] = kv.getKey();
4 }
5 }

进阶的时间要求想不出来,于是看了题解,有了以下收获:

题目最终需要返回的是前 kk 个频率最大的元素,可以想到借助堆这种数据结构,对于 kk 频率之后的元素不用再去处理,进一步优化时间复杂度。

  • 求前 k 大,用小根堆,求前 k 小,用大根堆

    •         PriorityQueue<int[]> minHeap = new PriorityQueue<>(k,
      new Comparator<int[]>() {
      @Override
      public int compare(int[] o1, int[] o2) {
      //升序
      return o1[1] - o2[1];
      //降序
      return o2[1] - o1[1];
      }
      });


  • topk (前k大)用小根堆,维护堆大小不超过 k 即可。每次压入堆前和堆顶元素比较,如果比堆顶元素还小,直接扔掉,否则压入堆。检查堆大小是否超过 k,如果超过,弹出堆顶。复杂度是 nlogk
  • 避免使用大根堆,因为你得把所有元素压入堆,复杂度是 nlogn,而且还浪费内存。如果是海量元素,那就挂了。
        PriorityQueue<int[]> minHeap = new PriorityQueue<>(k,
new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
}); int count = 0
for (Map.Entry<Integer, Integer> kv : map.entrySet()) {
//前K个键值对不需要判断
if (count++ < k) {
minHeap.add(new int[]{kv.getKey(), kv.getValue()});
} else if (kv.getValue() > minHeap.peek()[1]) {
minHeap.poll();
minHeap.add(new int[]{kv.getKey(), kv.getValue()});
}
}

leetcode347 —— n中topK && PriorityQueue(Heap) && Map遍历的更多相关文章

  1. 去除List集合中的重复对象,Map遍历代码

    /*** * 去除List<PartsInfoDTO>列表中的重复对象 ~!! * @param list * @return */ public static List<Parts ...

  2. jquery中的 ajax 以及map遍历

    1.语法 $.ajax{ type:'get',//类型 有get post url:'',//路径 data:{name:$('#ma').val(),nameq:$('#maq').val()}, ...

  3. js中三个对数组操作的函数 indexOf()方法 filter筛选 forEach遍历 map遍历

     indexOf()方法  indexOf()方法返回在该数组中第一个找到的元素位置,如果它不存在则返回-1. 不使用indexOf时 var arr = ['apple','orange','pea ...

  4. Java中Map遍历的四种方案

    在Java中如何遍历Map对象 方式一 这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Integer, Integer> map = new HashM ...

  5. java中Map遍历的四种方式

    在java中所有的map都实现了Map接口,因此所有的Map(如HashMap, TreeMap, LinkedHashMap, Hashtable等)都可以用以下的方式去遍历. 方法一:在for循环 ...

  6. Java集合中List,Set以及Map等集合体系详解

    转载请注明出处:Java集合中List,Set以及Map等集合体系详解(史上最全) 概述: List , Set, Map都是接口,前两个继承至collection接口,Map为独立接口 Set下有H ...

  7. Java中关于HashMap的元素遍历的顺序问题

    Java中关于HashMap的元素遍历的顺序问题 今天在使用如下的方式遍历HashMap里面的元素时 1 for (Entry<String, String> entry : hashMa ...

  8. map遍历的四种方式

    原文 http://blog.csdn.net/dayanxuqun/article/details/26348277 以下是map遍历的四种方式: // 一.推荐只用value的时候用,都懂的... ...

  9. ES6中的Set和Map集合

    前面的话 在ES6标准制定以前,由于可选的集合类型有限,数组使用的又是数值型索引,因而经常被用于创建队列和栈.如果需要使用非数值型索引,就会用非数组对象创建所需的数据结构,而这就是Set集合与Map集 ...

随机推荐

  1. NOIP模拟38:a

      这是T1.   考场上思路与正解就差个前缀,打的线段树,因为其巨大常数快乐挂掉......   正解复杂度是\(O(n^2m)\),其实再挂个\(log\)也能过,但是需要用常数极其优秀的树状数组 ...

  2. Java并发知识总结,超详细!

    首先给大家分享一个github仓库,上面放了200多本经典的计算机书籍,包括C语言.C++.Java.Python.前端.数据库.操作系统.计算机网络.数据结构和算法.机器学习.编程人生等,可以sta ...

  3. Mysql 面试宝典

    实时更新 你用过哪些数据库? mysql redis mysql 和 redis 的区别? 比较点 Mysql Redis 数据库类型 关系型 非关系型 作用 持久化层 存储需要持久化的数据,数据存在 ...

  4. C语言实现线程池功能

    1. 线程池基本原理 2. 线程池C语言实现 2.1 线程池的数据结构 #include <stdio.h> #include <pthread.h> #include < ...

  5. windows系统框架

  6. PHP中的数组分页实现(非数据库)

    在日常开发的业务环境中,我们一般都会使用 MySQL 语句来实现分页的功能.但是,往往也有些数据并不多,或者只是获取 PHP 中定义的一些数组数据时需要分页的功能.这时,我们其实不需要每次都去查询数据 ...

  7. TP6自带的跨域中间件无法使用的个人解决方法

    使用TP6,因为需要跨域上传图片,一直不成功,网上搜了好久,方法都没解决跨域上传文件 比如下面的方式没成功 $this->app = $app; $this->request = $thi ...

  8. windows 中cmd一些特殊命令

    chcp 65001  就是换成UTF-8代码页 chcp 936 可以换回默认的GBK chcp 437 是美国英语 shutdown -s -t 60   60秒后关机 shutdown /a  ...

  9. Docker系列(26)- 发布镜像到阿里云容器服务

    1.登录阿里云 2.找到容器镜像服务 3.创建命名空间 4.创建镜像仓库 5.上传镜像

  10. Linux系列(11) - PATH环境变量

    前言 在Liunx当中要想执行"执行脚本"."执行文件"或者"执行命令",需要用绝对路径:因此环境变量就出来了,将路径放到环境变量中,环境变 ...