[leetcode]堆排序 求前k大的数
前一篇博客中写到了排序算法,其中包含一个堆排序,因此本篇博客讲解堆这个数据结构及其应用。
关于最大堆最小堆以及初始建堆和整理堆在上篇博客中有提及,此处不再赘述。下面讲解一个堆的重要应用,求n个数中前k个大的数,一般思路是将n个数排序,取前k个数,但当n的数量庞大无法加载到内存时,需要另外一种思路,即利用堆,只维护k个树的大小而不需维护全部。
具体的思路是:先建一个k个数的小堆,然后从k+1个数往后的值与堆顶元素比较,若此数比堆顶元素大,就将堆顶元素用这个数替换,然后重新调整堆,以此向后重复上述过程,直到将N个数比较完成,那么此时组成这个堆的k个元素就是前k个大的数。
下面以leetcode上的题为例,实现这个求解过程。
347. Top K Frequent Elements
Given a non-empty array of integers, return the k most frequent elements.
For example,
Given [1,1,1,2,2,3]
and k = 2, return [1,2]
.
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
java中的优先队列PriorityQueue是一个具有小根堆性质的数据结构,并且可以通过提供comparator比较器实现大根堆或自定义排序。本题中要求统计数字出现次数,使用hashmap,并自定义数据结构完成数字到出现次数的一一映射,通过上面的思路,维护大小为k的小根堆,最后逆向输出。
class KeyValue{Integer key;Integer value;public KeyValue(Integer key,Integer value) {this.key=key;this.value=value;}}public List<Integer> topKFrequent(int[] nums, int k) {Map<Integer,Integer> map = new HashMap<>();//统计数字出现频率for(int i=0;i<nums.length;i++) {if(map.containsKey(nums[i])) {map.put(nums[i],map.get(nums[i])+1);} else {map.put(nums[i],1);}}Iterator iter = map.entrySet().iterator();Queue<KeyValue> queue = new PriorityQueue<>(k,new Comparator<KeyValue>() {public int compare(KeyValue value1,KeyValue value2) {return value1.value-value2.value;} });int cnt=0;while(iter.hasNext()) { //对hashmap中元组遍历Map.Entry entry = (Map.Entry) iter.next();KeyValue tmp = new KeyValue((Integer) entry.getKey(),(Integer) entry.getValue());if(cnt<k) { //k大小优先队列queue.add(tmp);} else if(tmp.value>queue.peek().value) { //比堆顶大,替换堆顶queue.poll();queue.add(tmp);}cnt++;}List<Integer> ret = new ArrayList<>();//小根堆逆向输出,频率大的在前 for(int i=0;i<k;i++) {ret.add(0,queue.poll().key);}return ret;}
[leetcode]堆排序 求前k大的数相关推荐
- 信息学奥赛一本通(1235:输出前k大的数)——堆排序
1235:输出前k大的数 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 12715 通过数: 4043 [题目描述] 给定一个数组,统计前k大的数并且把这 ...
- 算法题 求第K大的数
题目描述:在乱序数组中求第K大的数 思路:立刻想到的是当然先排序然后取数.但是提问者明显不是想这么解.上网查了下原来是快排思路. 利用快排的思想,从数组arr中随机找出一个元素X,把数组分成两部分ar ...
- C语言(CED)输出前k大的数(分治法/局部快速排序):给定一个数组,统计前k大的数并且把这k个数从大到小输出。
)输出前k大的数(分治法/局部快速排序):给定一个数组,统计前k大的数并且把这k个数从大到小输出. [输入] 第一行包含一个整数n,表示数组的大小. 第二行包含n个整数,表示数组的元素,整数之间以一个 ...
- 输出前k大的数(信息学奥赛一本通-T1235)
[题目描述] 给定一个数组,统计前k大的数并且把这k个数从大到小输出. [输入] 第一行包含一个整数n,表示数组的大小.n < 100000. 第二行包含n个整数,表示数组的元素,整数之间以一个 ...
- (分治)7617:输出前k大的数
描述 给定一个数组,统计前k大的数并且把这k个数从大到小输出. 输入 第一行包含一个整数n,表示数组的大小.n < 100000. 第二行包含n个整数,表示数组的元素,整数之间以一个空格分 ...
- C++ 输出前K大的数
1:输出前k大的数 查看 提交 统计 提问 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB 描述 给定一个数组,统计前k大的数并且把这k个数从大到小输出. ...
- 无序数组求第k大的数 python_整数无序数组求第K大数
import java.util.Scanner; /** * 类似与求第k小的问题 * 求第k大相当于求第n-k+1小,n为数组长度 * * 著名的BFPRT算法可保证在线性时间内得到结果. * h ...
- 【Leetcode】两个有序数组,求第k大的数
双指针: def func(num1,num2,k):i,j,n = 0,0,0while i<len(num1) or j<len(num2):n += 1if i<len(num ...
- 利用向量叉积求三角形的面积(+STL:nth_element求第K大的数)
牛客寒假算法集训营2 https://ac.nowcoder.com/acm/contest/327/A A.处女座的签到题 题目描述 平面上有n个点,问:平面上所有三角形面积第k大的三角形的面积是多 ...
最新文章
- 将一个一维数组转化为二进制表示矩阵。例如_算法之矩阵最大区域问题
- Java 线程同步 synchronized
- Navicat for SQLite 15中文版
- 蓝桥杯第六届决赛真题大全解(java版本)
- 【译】Diving Into The Ethereum VM Part 4 - How To Decipher A Smart Contract Method Call
- 软设考试笔记--UML建模
- 卷积的物理意义(经典)
- Linux内核的l2tp实现,Linux Kernel gdth实现内核内存破坏漏洞
- 计算机信息加工的类型及举例,3.1.2计算机信息加工的过程和类型
- 接入淘宝API(PHP版本)
- jsoup Java HTML解析器
- 动态规划时间复杂度_算法分析与设计之动态规划
- HEX2BIN不能在win7_64位下执行的Keil官方解决方案
- 小白教程 微信小程序 官方示例Demo下载及运行
- 网络安全-终端安全检测和防御技术
- 绝对值线性化的两种方式
- Win7电脑如何关闭智能卡服务功能--win10专业版
- 工业镜头倍率及视场范围、焦距的计算方法
- [分享]高手是怎样炼成的:精妙SQL语句介绍
- 基于高光谱影像的农作物检测应用简介