题目:输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。

一个简单的方法就是排序,先将这n个数按从大到小排序,最快需要O(nlogn)的时间,然后可以在O(1)时间内将K个数取出,显然这不是我们想要的结果。
我们可以给出一个容器,这个容器刚好能存放k个数,依次扫描N个整数,如果容器里数的个数小于K,那么直接将当前扫描到的整数存放到容器中,否则,将当前整数与容器中的最大数比较,如果比容器中的最大数还要大,那么将其抛弃,否则将容器中的最大数删除,将当前整数插入。
因此,我们只要对N个整数做三件事
1.在K个整数中找到最大数
2.在容器中删除最大数
3.插入一个新的数字
容器的数据结构可以用大根堆来实现,所以三步加起来在O(1)时间内可以完成(1:O(1);2,3:O(logK))
N个数总共要O(NlogK)时间复杂度明显提高
在C++中,我们还可以用基于红黑树的multiset数据结构来实现,下面是何海涛博客中的代码,贴出来,大家参考下
typedef multiset<int, greater<int> >  IntHeap;
void FindKLeastNumbers
(
      const vector<int>& data,               // 所有的整数数据
      IntHeap& leastNumbers,                 // 输出K个最小的整数
      unsigned int k                            //表示容器的大小 
)
{
      leastNumbers.clear();              //清空该容器
      if(k == 0 || data.size() < k)    //排除特殊情况,鲁棒性
            return;
      vector<int>::const_iterator iter = data.begin();
      for(; iter != data.end(); ++ iter)
      {
            //如果当前容器里的整数个数还没有达到K个,那么直接将当前整数插入到容器中
            if((leastNumbers.size()) < k)
                  leastNumbers.insert(*iter);

//否则
            else
            {
                  //第一步 找出容器中的最大的整数
                  IntHeap::iterator iterFirst = leastNumbers.begin();
                  //第二步 比较当前整数与容器中最大整数的大小,如果小于
                  if(*iter < *(leastNumbers.begin()))
                  {
                        //替换掉容器中的最大整数
                        leastNumbers.erase(iterFirst);
                        leastNumbers.insert(*iter);
                  }
            }
      }
}
本篇文章对应何海涛博客
http://zhedahht.blog.163.com/blog/static/2541117420072432136859

何海涛算法面试题感悟之五:查找最…相关推荐

  1. 何海涛算法面试题感悟之一:将二叉…

    题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树                                     ...

  2. 何海涛算法面试题感悟之六:二元查…

    题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: 8   ...

  3. 何海涛算法面试题感悟之二:设计包…

    题目:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素.要求函数min.push以及pop的时间复杂度都是O(1) 如果没有min,该栈可以很轻松地构造出来,现在添加了一个min功能,首 ...

  4. 何海涛算法面试题感悟之四:二元树…

    题目:输入一个整数和一棵二元树.从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径.打印出和与输入整数相等的所有路径. 例如输入整数22和如下二元树 10                 ...

  5. 何海涛算法面试题感悟之九:寻找链…

    题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下: struct ListNode {       int       m_nKey;      ...

  6. 何海涛算法面试题感悟之三:子数组…

    题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.要求时间复杂度为O(n). 例如输入的数组为1, -2, 3, ...

  7. [Z]谷歌(Google)算法面试题

    谷歌(Google)算法面试题 1.谷歌面试题:给定能随机生成整数 1 到 5 的函数,写出能随机生成整数 1 到 7 的函数. 回答:此题的关键是让生成的 1 到 7 的数出现概率相同. 只要我们可 ...

  8. prim算法_历时两月,终拿字节跳动offer,算法面试题分享「带答案」

    欢迎关注专栏<Java架构筑基>--专注于Java技术的研究与分享! Java架构筑基​zhuanlan.zhihu.com Java架构筑基--专注于Java技术的研究与分享! 后续文章 ...

  9. 66 道前端算法面试题附思路分析助你查漏补缺

    大家好,我是漫步. 今天来分享一篇干货,前端关于算法的分析不多,下文列举了66道前端算法面试题,希望对你有所帮助. 作者:Eno_Yao https://segmentfault.com/a/1190 ...

最新文章

  1. “未能为域创建GPO 出现扩展错误”的解决办法
  2. 【jQuery】用jQuery给文本框添加只读属性【readOnly】
  3. Error loading MySQLdb module: No module named MySQLdb
  4. Winform中设置Dialog的显示位置居中
  5. Java 集合 ArrayList 需要知道的几个问题
  6. java 生成token代码_java token生成和校验的实例代码
  7. 420集的python教程下载_阿里达摩院推荐的420集的python教程,据说懂中文就能入门高清版...
  8. 有轻功:用3行代码让Python数据处理脚本获得4倍提速
  9. OSI参考模型(应用层、表示层、会话层、传输层、网络层、数据链路层、物理层)...
  10. __builtin_popcount
  11. 035 spring amqp
  12. 05. Django基础:请求和响应
  13. 使用Cron和PHP检测网页是否被篡改
  14. 脚本文件不变色_LoadRunner脚本开发
  15. java 网页版通讯_JavaWeb网页聊天室(WebSocket即时通讯)
  16. 鱼眼镜头的成像原理到畸变矫正(完整版)
  17. layui数据表格动态cols(字段)动态变化
  18. 阿里云国际9款免费标签云生成工具
  19. C语言编程实现程输出所有玫瑰花数
  20. javac错误:javac不是内部或外部命令 也不是可运行的程序 解决方法

热门文章

  1. 带你了解GDT陶瓷气体放电管的类型、优势、特性以及工作原理
  2. css样式表的三种方式
  3. 计算机学院网站规划书,计算机学院网站设计与实现 -毕业论文.docx
  4. Java中调用ImageJ,与直接使用ImageJ软件处理所得图片黑白颠倒的问题
  5. 什么是聚簇索引和非聚簇索引?
  6. Link-aggregation端口聚合
  7. [Linux][问题解决]Linux访问本地网站可以,但是外部访问不行
  8. 斯坦福教授研究了美国200年专利数据: 论文发得多?不等于创新!
  9. Google 收购摩托罗拉移动将会对全球手机市场格局带来哪些深远影响?
  10. Catia启动界面图片修改