前 K 个高频元素问题

作者:Grey

原文地址: 前 K 个高频元素问题

题目描述

LeetCode 347. Top K Frequent Elements

思路

第一步,针对数组元素封装一个数据结构

public class Node {
int v;
int t;
public Node(int value, int times) {
v = value;
t = times;
}
}

其中v表示数组元素,t表示数组元素出现的次数。

第二步,使用哈希表把每个元素的词频先存一下。其中key是数组元素,valueNode类型,封装了数组元素和次数。

        Map<Integer, Node> freqMap = new HashMap<>();
for (int n : arr) {
if (freqMap.containsKey(n)) {
// 存在就把词频加一
freqMap.get(n).t++;
} else {
// 不存在就新建一个词频
freqMap.put(n, new Node(n, 1));
}
}

第三步,使用一个小根堆,按词频从小到大。我们需要将这个小根堆维持在K个高频元素。具体做法如下

如果堆未超过K个元素,可以入堆;

如果堆已经到了K个元素了,就看堆顶的元素出现的次数是否比即将要遍历的元素出现的次数少,如果堆顶元素出现的次数比即将要遍历的元素少,

说明即将遍历的元素比堆顶元素更高频,可以替换掉堆顶元素,将其入堆;

如果堆已经超过K个元素了,那么弹出元素,让堆始终保持在K个元素。

第四步,弹出堆中所有元素,即为前K个高频元素。

完整代码如下:

    public static class Node {
// 值
public int v;
// 次数
public int t; public Node(int value, int times) {
v = value;
t = times;
}
} public static int[] topKFrequent(int[] arr, int k) {
if (arr == null || arr.length == 0 || arr.length < k) {
return null;
}
Map<Integer, Node> freqMap = new HashMap<>();
for (int n : arr) {
if (freqMap.containsKey(n)) {
freqMap.get(n).t++;
} else {
freqMap.put(n, new Node(n, 1));
}
}
// 字符种类没有k个,无法得到结果
if (freqMap.size() < k) {
return null;
}
int[] ans = new int[k];
PriorityQueue<Node> topK = new PriorityQueue<>(k, Comparator.comparingInt(o -> o.t));
for (Map.Entry<Integer, Node> entry : freqMap.entrySet()) {
if (topK.size() <= k || topK.peek().t < entry.getValue().t) {
topK.offer(entry.getValue());
}
if (topK.size() > k) {
topK.poll();
}
}
int i = 0;
while (!topK.isEmpty()) {
ans[i++] = topK.poll().v;
}
return ans;
}

更多

算法和数据结构笔记

前 K 个高频元素问题的更多相关文章

  1. 【LeetCode题解】347_前K个高频元素(Top-K-Frequent-Elements)

    目录 描述 解法一:排序算法(不满足时间复杂度要求) Java 实现 Python 实现 复杂度分析 解法二:最小堆 思路 Java 实现 Python 实现 复杂度分析 解法三:桶排序(bucket ...

  2. Top K Frequent Elements 前K个高频元素

    Top K Frequent Elements 347. Top K Frequent Elements [LeetCode] Top K Frequent Elements 前K个高频元素

  3. LeetCode:前K个高频元素【347】

    LeetCode:前K个高频元素[347] 题目描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [ ...

  4. 代码题(3)— 最小的k个数、数组中的第K个最大元素、前K个高频元素

    1.题目:输入n个整数,找出其中最小的K个数. 例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 快排思路(掌握): class Solution { public ...

  5. leetcode347. 前 K 个高频元素

    题目最终需要返回的是前 kk 个频率最大的元素,可以想到借助堆这种数据结构,对于 kk 频率之后的元素不用再去处理,进一步优化时间复杂度. 具体操作为: 借助 哈希表 来建立数字和其出现次数的映射,遍 ...

  6. Java实现 LeetCode 347 前 K 个高频元素

    347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前 k 高的元素. 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输 ...

  7. 力扣 - 347. 前 K 个高频元素

    目录 题目 思路1(哈希表与排序) 代码 复杂度分析 思路2(建堆) 代码 复杂度分析 题目 347. 前 K 个高频元素 思路1(哈希表与排序) 先用哈希表记录所有的值出现的次数 然后将按照出现的次 ...

  8. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

  9. leetcode 347. 前 K 个高频元素

    问题描述 给定一个非空的整数数组,返回其中出现频率前 k 高的元素.   示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums ...

随机推荐

  1. 浅谈 TCP、IP、DNS 和 HTTP 的关系

    一.浅谈三个协议的基本概念 1.IP 协议 按层次分,IP网际协议位于网络层,几乎所有的网络的系统都会用到 IP 协议,其重要性非同一般.IP 协议作用就是把各种数据包传送给对方,对方的地址就要看其 ...

  2. [AcWing 35] 反转链表

    迭代版本 点击查看代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next ...

  3. python数据可视化-matplotlib入门(6)-从文件中加载数据

    前几篇都是手动录入或随机函数产生的数据.实际有许多类型的文件,以及许多方法,用它们从文件中提取数据来图形化. 比如之前python基础(12)介绍打开文件的方式,可直接读取文件中的数据,扩大了我们的数 ...

  4. 2003031121——浦娟——Python数据分析第七周作业——MySQL的安装及使用

    项目 要求 课程班级博客链接 20级数据班(本) 作业要求链接 Python第七周作业 博客名称 2003031121--浦娟--Python数据分析第七周作业--MySQL的安装及使用 要求 每道题 ...

  5. Vue-router(前端路由)的两种路由模式

    Vue的两种路由模式: hash.history:默认是hash模式: 前端路由(改变视图的同时不会向后端发出请求) 一.什么是hash模式和history模式? hash模式:是指url尾巴后的#号 ...

  6. Redis设计与实现2.1:数据库和事件

    数据库和事件 这是<Redis设计与实现>系列的文章,系列导航:Redis设计与实现笔记 数据库 数据库的结构定义在 redis.h/redisServer 这个结构体中,这个结构体有许多 ...

  7. 宽字符输出中文,Devc++解决方法

    有群友问类似问题,然后我编译了一下试试: #include <stdio.h> #include <wchar.h> #include <locale.h> int ...

  8. 学习Java的第十七天——大数字运算

    学习内容:大数字运算 代码实现: package 数字处理类; import java.math.BigInteger; public class BigIntegerDemo { public st ...

  9. 项目下载依赖后面加 -S -D -g 分别代表什么意思

    npm install name -S此依赖是在package的dependencies中,不仅在开发中,也在打包上线后的生产环境中,比如vue npm install name -D此依赖是在pac ...

  10. Spring大事务到底如何优化?

    所谓的大事务就是耗时比较长的事务. Spring有两种方式实现事务,分别是编程式和声明式两种. 不手动开启事务,mysql 默认自动提交事务,一条语句执行完自动提交. 一.大事务产生的原因 操作的数据 ...