毫无疑问,TOP-K问题太太太太重要了,尤其是面试中。之前在学校专业英语课程中简单分享过大数据处理中Hadoop(分布式计算开源框架)的相关知识,也是从TOP-K问题入手的。
在看了很多相关的博文之后,有很多伙伴也介绍的很详细,但是我认为接下来分享的大神(大大大神)的文章讲的清楚的一批:

58沈剑 架构师之路

为了自己方便看,以及之后丰富此篇章的内容,就直接截下来了。















不得不说,讲的太清晰了,当然,各种方法的具体实现还是要认真掌握的。

其实之前还了解到一种方法就是BitMap(位图法),这个bitmap,
还有和位图相关的Bloom_Filter(布隆过滤器)(其实在学校高级算法课程的结课报告就是关于这个)我也想具体整理学习一下,期待后续

关于TOP-K问题,于是我又找到了大神的另一篇(应该是)
链接:bitmap计数,求TopK最快的方法

以下是内容:
空间换时间,是算法优化中最常见的手段,如果有相对充裕的内存,可以有更快的算法。

画外音:即使内存不够,也可以水平切分,使用分段的方法来操作,减少每次内存使用量。

TopK问题描述

从arr[1, 12]={5,3,7,1,8,2,9,4,7,2,6,6} 这n=12个数中,找出最大的k=5个。

比特位图(bitmap)法

bitmap,是空间换时间的典型代表。它是一种,用若干个bit来表示集合的数据结构。

例如,集合S={1,3,5,7,9},容易发现,S中所有元素都在1-16之间,于是,可以用16个bit来表示这个集合:存在于集合中的元素,对应bit置1,否则置0。

画外音:究竟需要多少存存储空间,取决于集合中元素的值域,在什么范围之内。

上述集合S,可以用1010101010000000这样一个16bit的bitmap来表示,其中,第1, 3, 5, 7, 9个bit位置是1。

假设TopK的n个元素都是int,且元素之间没有重复,只需要申请2^32个bit,即512M的内存,就能够用bitmap表示这n元素。

扫描一次所有n个元素,以生成bitmap,其时间复杂度是O(n)。生成后,取TopK只需要找到最高位的k个bit即可。算法总时间复杂度也是O(n)。

伪代码为:

bitmap[4G] = make_bitmap(arr[1, n]);

return bitmap[top k bits];

bitmap算法有个缺点,如果集合元素有重复,相同的元素会被去重,(这个也会有位图去重相关的知识)

假设集合S中有5个1,最终S制作成bitmap后,这5个1只对应1个bit位,相当于4个元素被丢掉了,这样会导致,找到的TopK不准。该怎么优化呢?

比特位图计数

优化方法是,每个元素的1个bit变成1个计数。


如上图所示,TopK的集合经过比特位图计数处理后,会记录每个bit对应在集合S中出现过多少次。

接下来,找TopK的过程,就是bitmap从高位的计数开始
往低位的计数扫描得到count之和等于k,对应的bit就是TopK所求。


如上图所示,k=5:

(1)第一个非0的count是1,对应的bit是9;

(2)第二个非0的count也是1,对应的bit是8;

(3)第三个非0的count是2,对应的bit是7;

(4)第四个非0的count是2,对应的bit是6,但TopK只缺1个数字了,故只有1个6入选;

故,最终的TopK={9, 8, 7, 7, 6}。

结论:通过比特位图精准计数的方式,求解TopK,算法整体只需要不到2次扫描,时间复杂度为O(n),比减治法的随机选择会更快。

为了巩固今天的内容,例行挖个坑。

面试中,还有个问题问得比较多:求一个正整数的二进制表示包含多少个1?

例如:7的二进制表示是111,即7的二进制表示包含3个1。

画外音:我面试过程中从不问这个问题。

最常见的解法是:

#include<iostream>using namespace std;uint32_t count_one(uint32_t n){uint32_t count=0;while(n){count ++;n &= (n-1);}return count;}int main()
{cout<<count_one(32767);return 0;
}

这里又有需要注意的点:uint32_t,关于数据类型的知识。

以上就是大概的TOP-K问题的学习和解决,当然最好是要手撕一个代码(经典的堆,当然还有堆的实现)大家都学废了吗哈哈哈

任重道远,加油!

TOP-K问题(清晰,巨全)相关推荐

  1. 找出无序数组中最小的k个数(top k问题)

    2019独角兽企业重金招聘Python工程师标准>>> 给定一个无序的整型数组arr,找到其中最小的k个数 该题是互联网面试中十分高频的一道题,如果用普通的排序算法,排序之后自然可以 ...

  2. 程序员编程艺术:第三章续、Top K算法问题的实现

    程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha.     致谢:微软100题实现组,狂想曲创作组.     时间:2011年05月08日    ...

  3. 《恋上数据结构第1季》二叉堆原理及实现、最小堆解决 TOP K 问题

    二叉堆 BinaryHeap 堆(Heap) 堆的出现 堆简介 二叉堆(Binary Heap) 获取最大值 最大堆 - 添加 最大堆 - 添加优化 最大堆 - 删除 replace 最大堆 - 批量 ...

  4. 海量数据处理的 Top K相关问题

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 Top-k的最小堆解决方法 问题描述:有N(N>>10000)个整数,求出其中的前K个最大的数.(称作Top k或者Top ...

  5. 典型的Top K算法_找出一个数组里面前K个最大数

    原文 典型的Top K算法_找出一个数组里面前K个最大数...或找出1亿个浮点数中最大的10000个...一个文本文件,找出前10个经常出现的词,但这次文件比较长,说是上亿行或十亿行,总之无法一次读入 ...

  6. Top K问题系列之三 手写代码

    Top K问题是面试时手写代码的常考题,某些场景下的解法与堆排和快排的关系紧密,所以把它放在堆排后面讲. 关于Top K问题最全的分类总结是在这里(包括海量数据的处理),个人将这些题分成了两类:一类是 ...

  7. 【分步详解】两个有序数组中的中位数和Top K问题

    我现在在做一个叫<leetbook>的开源书项目,把解题思路都同步更新到github上了,需要的同学可以去看看 地址:https://github.com/hk029/leetcode 这 ...

  8. 【数据结构】二叉堆、TOP K 问题

    二叉堆.TOP K 问题 堆(Heap) 堆的出现,思考? 堆简介 二叉堆(Binary Heap) 获取最大值 最大堆 - 添加 最大堆 - 添加优化 最大堆 - 删除 replace 最大堆 – ...

  9. 堆实战(动态数据流求top k大元素,动态数据流求中位数)

    动态数据集合中求top k大元素 第1大,第2大 ...第k大 k是这群体里最小的所以要建立个小顶堆 只需要维护一个大小为k的小顶堆 即可当来的元素(newCome)> 堆顶元素(smallTo ...

最新文章

  1. Matlab中fft作频谱横纵坐标
  2. Java学习笔记(43)——Java泛型
  3. java复制两个对象报异常_Java中复制两个不同类的对象的属性
  4. 记录一下Memcached的用法:
  5. python练习--模拟grep -B功能
  6. 解题报告——例题5-8 Unix is 命令(UVa 400)——26行代码解决
  7. 微信小程序开发:学习笔记[9]——本地数据缓存
  8. MySQL 8数据导入 MySQL 5.7
  9. WordPress搬家插件迁移网站的方法(从一台服务器搬到另一台服务器)
  10. 使用win7超级终端连接华为交换机并配置端口镜像
  11. 只应对不预测、减少焦虑
  12. 10.6 全源(All pairs)负权Johnson算法
  13. 51单片机(十)—— 8位数码管-数码管扫描
  14. CSR8615 蓝牙4.0音响模块
  15. C语言二刷第七天:字符串(mooc视频;老师:翁恺)
  16. 【软件需求工程】北理的恶龙们01——需求获取阶段准备工作
  17. 包和工具(读书笔记)
  18. word插入向上向下取整符号
  19. 微信公众号简易入门教程
  20. word表格分开快捷键_Word拆分与合并单元格快捷键

热门文章

  1. Linux安装jdk和docker安装jdk
  2. 数据结构:实现图书信息管理系统
  3. 如何改域的NETBIOS名?
  4. php程序检测不到vc9,XAMPP2016中文精简版启动失败 缺少运行库解决办法
  5. 软件设计师教程(十三)计算机系统知识-软件系统分析与设计
  6. 【Python】批量移动同类型文件到其他文件夹的办公技巧
  7. java 微秒 时间_Java中时间的计算 年月日小时分钟秒毫秒微秒
  8. 批处理删除注册表分支方法
  9. 微信小程序截图分享 图片不清晰
  10. 微机原理与接口技术:微型计算机输入输出接口 详细笔记与例题