当前位置:   article > 正文

leetcode347——前K个高频元素——java实现_leetcode 前 k 个高频元素 用最大堆 java

leetcode 前 k 个高频元素 用最大堆 java

题目要求:
在这里插入图片描述
分析:
这种题目又来了,根深蒂固的HashMap思想绝对是呼之欲出。于是不假思索,先用HashMap求出每个数字有几个再说。
求出每个数字的频率之后,我们想要求出第k高的频率的元素,并且时间复杂度必须优于O(nlog n),那么该如何求呢?
我们应该想到,堆的时间复杂度正好是O(nlog n),可以用堆来求。而堆是可以利用优先队列PriorityQueue来求的。
我们想要求出第k个频率的数字,那么肯定要堆这些数字出现的次数进行排列,那么优先队列正好是最合适的求法,我们可以让它最先pop出来的是最大值,至于这个排序方法,就是利用匿名内部类,把compare方法给重写一下,这个方法已经用过多次了。
然后就可以取出map中的key值与优先队列中的peek值进行比较了,如果队列没满(队列的容量为k),则将他们加入进来,如果队列满了,并且现在遍历到的这个值大于队列中的peek值,就把队列中最小的给remove掉,然后把这个值给add进去。
最后只要把优先队列中的值给弹出,然后再add到list中去就可以了。

具体代码如下:

class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
        if(nums == null || nums.length == 0)
            return new ArrayList<>();
        Map<Integer, Integer> map = new HashMap<>();
        for(int num : nums) {
            if(!map.containsKey(num)) {
                map.put(num, 1);
            } else {
                map.put(num, map.get(num) + 1);
            }
        }
        // 遍历map,用最小堆保存频率最大的k个元素
        PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer a, Integer b) {
                return map.get(a) - map.get(b);
            }
        });
        //将Map中所有的键存入到set集合中
        for (Integer key : map.keySet()) {
            if (pq.size() < k) {
                pq.add(key);
            } else if (map.get(key) > map.get(pq.peek())) {
                pq.remove();
                pq.add(key);
            }
        }
        // 取出最小堆中的元素
        List<Integer> list = new ArrayList<>();
        while (!pq.isEmpty()) {
            list.add(pq.remove());
        }
        return list;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/72745
推荐阅读
  • LeetCode707.设计链表设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性prev以指示链... [详细]

  • 设计链表实现。您可以选择使用单链表或双链表。单链表节点应该具有两个属性val和next。val是当前节点值,next是指向下一个节点指针/引用。如果要使用双向链表,则还需要一个属性prev以指示链表上一个节点。假设链表所... [详细]

  • 题目设计实现。您可以选择使用单或双。单中的节点应该具有两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果要使用双向,则还需要一个属性prev以指示中的上一个节点。假设中... [详细]

  • Leetcode707.设计链表题目设计链表实现。您可以选择使用单链表或双链表。单链表节点应该具有两个属性:val和next。val是当前节点值,next是指向下一个节点指针/引用。如果要使用双向链表,则还需要一个属性prev以指... [详细]

  • 题目描述:设计的实现。您可以选择使用单或双。单中的节点应该具有两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果要使用双向,则还需要一个属性prev以指示中的上一个节点。假设... [详细]

  • 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性prev以指示链表中的上一个节点。假设链表中的所... [详细]

  • -定义自定义属性-->5.2.10.RELEASE4.12【JavaMaven进阶学习目标理解分模块开发的意义能够使用聚合工程快速构建项目能够使用继承简... [详细]

  • 一、接口的默认方法Java8允许我们给接口添加一个非抽象的方法实现,只需要使用default关键字即可,这个特征又叫做扩展方法interfaceFormula{doublecalculate(inta);defaultdoublesqrt(... [详细]

  • 一、双冒号“::”就是Java方法引用(Methodreferences)方法引用格式是类名::方法名。一般是用作Lambda表达式。形如ClassName::methodName或者objectName::methodName表达... [详细]

  • java1.8下载安装配置教程_java1.8下载java1.8下载1.下载1.1.官网下载官网下载地址:JavaDownloads|Oracle1.2.百度网盘下载下载地址:网盘地址2.安装2.1.双击exe文件2.2.安装jdk点击【更... [详细]

  • 目录一、基础知识1)为什么要学习Java82)行为参数化3)初识Lambda二、函数式数据处理1)流的使用2)流和集合3)流的操作4)流的构建5)收集器的使用6)分组的使用三、学会使用Optional1)防御式检查2)学会使用Option四... [详细]

  • Java8的主要新语法特性如下:Lambda表达式Lambda表达式使Java程序员能够编写更加简洁、易读和易维护的代码。它是一种匿名函数,可以将其作为参数传递给其他方法或函数。方法引用方法引用是指通过名称来引用现有的方法,从而让代码变得更... [详细]

  • 集合——有时称为容器——是一个对象,它将多个元素组合成一个单元。集合用于存储、检索、操作和通信聚合数据。集合框架表示和操作集合的统一体系结构。组成接口表示集合的抽象数据类型。接口允许对集合进行独立于其表示细节的操作。在面向对象语言中,接口通... [详细]

  • 文章目录1:对List对象的某个属性进行排序这里对java8常用方法进行总结1:对List对象的某个属性进行排序降序pageList.getRecords().stream().sorted(Comparator.comparing(Sys... [详细]

  • 1、Lambda演变过程@Data@ToString@NoArgsConstructor@AllArgsConstructorpublicclassStudent{//名字privateStringname;//性别privateStrin... [详细]

  • 前段时间面了完美世界,被问到Java8特性,在此特地记录一下,虽然现在Java的版本可能已经很高了,但是Java8特性依然值得学习一下!_java8特性java8特性简介:前段时间面了完美世界,被问到Java8特性,在此特地... [详细]

  • Java8新特性快速入门,有这一篇就够了_java8特性java8特性一、Lambda表达式Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一... [详细]

  • 前言:越来越多的项目已经使用Java8了,毫无疑问,Java8JavaJava5(发布于2004年)之后的最重要的版本。这个版本包含语言、编译器、库、工具和JVM等方面的十多个特性。Java8是一次变化巨大的更,耗费了工程师大量的时... [详细]

  • 一、类1.1类修饰符A.Object是所有类的父类。B.包括数组在内的所有对象都实现了Object类中的方法。1.2类结构图二、字段1.1字段列表无。三、方法3.1方法列表注:如上图,共有12个方法。另外包含了一个静态代码块。绿色打开的锁代... [详细]

  • 大家好,我是大明哥,一个专注「」系列创作的硬核程序员。。Java现在发布的版本很快,每年两个,但是真正会被大规模使用的是3年一个的LTS版本。在Java版本中,一个特性的发布都会经历孵化阶段、预览阶段和正式版本。其中孵化和预览可能会跨越多个... [详细]

相关标签
  

闽ICP备14008679号