关于“最小的K个数”问题
从一堆无序的数中(共n个数)找到最小的K个数,这也算是一道比较经典的题目了,关于这道题目的解法,一般有几种:
方法1:先对所有的数据进行排序,然后直接找出前K个数来,即最小的K个数。时间复杂度为O(N*logN)。
方法2:采用类似快排的思想,只要找到第K小的数值的位置的话,那么数组中的前K个数值一定是最小的K个数,但是这K个数不一定是排好序的,关于找到第K个小的数值的方法卡参考我之前的文章:http://www.cnblogs.com/wangkundentisy/p/8810077.html。
当然,也可以参考《剑指offer(第二版)》面试题40。这种方法的期望时间复杂度为O(N),但是适用于大多数情况;最坏情况下时间复杂度可达到O(N^2)。
方法3:利用一个大顶堆,具体过程如下:
选取数据中前K个数(或者任意K个数)构成一个大顶堆,这个堆的根节点就是这K个数中的最大值,然后从剩余的n-K个数中依次找一个数与根节点的数比较,如果比根节点的数大的话,则跳过;如果比根节点的数小的话,就把根节点删除,并把这个数值加入到这个堆中,然后再把这个堆调整成大顶推,重复上述过程,直到比较完剩余的n-k个数。
这种方法的时间复杂度为O(N*logK)。
方法4:利用堆排序的思想,建立一个大小为n的小顶堆,由于小顶堆的顶点一定是n个数中的最小值,所以每次删除根节点,然后在调整堆,重复K次,就能找到最小的K个值了。(与堆排序的过程一致)这种算法的时间复杂度为O(K*logN)。
==================================================================================================分割线=================================================
1.当n的值不是很大时,以上几种方法的性能相差并不是很大,通常方法2用的比较多。
2.那么当n很大的时候,方法1和方法2就不适用了。通常采用方法3。(关于海量数据处理的问题可参考july的博客:https://blog.csdn.net/v_july_v/article/details/7382693)那么,为什么不能采用方法4呢?以下是个人的一些见解:
在n非常大的时候,数据需要存到硬盘上,而K相对却很小,采用方法3的话,可以在内存上轻易维护大小为K的堆的情况下,在减少磁盘I/O上会有一定的优势,因为每个元素只需要被读取一次。即方法3只需将大小为K的堆写入内存,而方法4需要将所有的n个数据写入内存,相比而言方法3对内存要求更小,更具有优势。所以,在有限的资源下,海量数据处理问题,通常采用方法3.
关于“最小的K个数”问题的更多相关文章
- 剑指Offer面试题:27.最小的k个数
一.题目:最小的k个数 题目:输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 这道题是典型的TopK问题,其最简单的思路莫过于 ...
- 算法练习:寻找最小的k个数
参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...
- 剑指Offer:面试题30——最小的k个数(java实现)
问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...
- 输入一个数组,求最小的K个数
被这道题困了好久,看了剑指Offer才知道OJ上的要求有点迷惑性. 题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 一 ...
- 1046: 最小的K个数
1046: 最小的K个数 时间限制: 1 Sec 内存限制: 128 MB提交: 233 解决: 200[提交][状态][讨论版] 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1 ...
- 最小的K个数:用快排的思想去解相关问题
实现快速排序算法的关键在于先在数组中选择一个数字,接下来把数组中的数字分为两部分,比选择的数字小的数字移到数组的左边,比选择的数字大的数字移到数组的右边. 这个函数可以如下实现: int Partit ...
- 剑指offer面试题30:最小的k个数
一.题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.解题思路 1.思路1 首先对数组进行排序,然后取出前k个数 ...
- 最小的k个数
// 最小的k个数.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include & ...
- 窥探算法之美妙——寻找数组中最小的K个数&python中巧用最大堆
原文发表在我的博客主页,转载请注明出处 前言 不论是小算法或者大系统,堆一直是某种场景下程序员比较亲睐的数据结构,而在python中,由于数据结构的极其灵活性,list,tuple, dict在很多情 ...
- 求一个数组中最小的K个数
方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如 ...
随机推荐
- shell脚本-预定义常量
$0 这个程式的执行名字$n 这个程式的第n个参数值,n=1..9$* 这个程式的所有参数,此选项参数可超过9个.$# 这个程式的参数个数$$ 这个程式的PID(脚本运行的当前进程ID号)$! 执行上 ...
- 【bug-劫持】深信服劫持
深信服的 HTTP 劫持有办法解决嘛 劫持js 当前页面打开下载地址,chrome是弹出保存窗口不刷新页面的,但劫持了就刷新页面了 连wifi(电信)和4g(联通)都一样
- js的调用方式
1.元素绑定 给具体的元素绑定JS的事件 事件:由用户行为触发的操作(鼠标操作,键盘操作) 语法:<标签 事件函数名="JS代码"> et: onclick:单机事件 ...
- iphone上点击div会出现半透明灰色背景以及margin失效
-webkit-tap-highlight-color 这个属性只用于iOS (iPhone和iPad).当你点击一个链接或者通过Javascript定义的可点击元素的时候,它就会出现 ...
- 启动tomcat报错:Failed to start component [StandardEngine[Catalina].StandardHost[localhost]
1.右键点击需要启动的tomcat,选择Clean和Clean Tomcat Work Directory,清除即可!
- Python算法——递归思想
编程语言在构建程序时的基本操作有:内置数据类型操作.选择.循环.函数调用等,递归实际属于函数调用的一种特殊情况(函数调用自身),其数学基础是数学归纳法.递归在计算机程序设计中非常重要,是许多高级算法实 ...
- java-BigDecimal类
1.BigDecimal类的概述和方法使用 * A:BigDecimal的概述 * 由于在运算的时候,float类型和double很容易丢失精度. * 所以,为了能精确的表示.计算浮点数,Java提供 ...
- oracle ZHS16GBK的数据库导入到字符集为AL32UTF8的数据库(转载+自己经验总结)
字符集子集向其超集转换是可行的,如此例 ZHS16GBK转换为AL32UTF8. 导出使用的字符集将会记录在导出文件中,当文件导入时,将会检查导出时使用的字符集设置,如果这个字符集不同于导入客户端的N ...
- Js判断字符的种类
Js判断字符的种类:unicode范围: 48-57:0-9 数字字符 65-90:A-Z 大写字母 97-122: a-z 小写字母 19968-40869:汉字 其他字符 实例:输出 ...
- 针对IE9的CSS兼容
(自己亲自试过有用)针对IE9的CSS只需在相应CSS代码加入只有IE9识别的 \9\0.具体代码如下: .div{ background-color:#0f0\9\0;/* ie9 */ } 其他浏 ...