bitmap计数,求TopK最快的方法?

简介: 《TopK到底怎么答?》介绍了TopK的四种解法,其中随机选择 (randomized select) 最为经典,用减治法 (Reduce & Conquer) 的思想,将数据规模急速降低,总体复杂度为O(n)。

《TopK到底怎么答?》介绍了TopK的四种解法,其中随机选择 (randomized select) 最为经典,用减治法 (Reduce & Conquer) 的思想,将数据规模急速降低,总体复杂度为O(n)。

结尾挖了一个坑:求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,即4G的内存,就能够用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个计数。

image.png

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

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

image.png

如上图所示,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。

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

最常见的解法是:

uint32_t count_one(uint32_t n){

    uint32_t count=0;

    while(n){

        count ++;

        n &= (n-1);

    }

    return count;

}

提问:还有多少种更快的方法呢?

image.png
架构师之路-分享可落地的架构文章

目录
相关文章
|
运维 Cloud Native 测试技术
极氪汽车云原生架构落地实践
随着极氪数字业务的飞速发展,背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验,并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。
|
3月前
|
存储 API 数据库
RAG检索增强怎么搭建:从原理到落地的完整路径
RAG(检索增强生成)通过“先检索、再生成”机制,将外部知识库与大模型结合,解决幻觉、数据过时及私有数据不可用问题。涵盖文档解析、文本分块、向量化存储、检索生成四大环节,强调分块策略、检索质量与提示词约束的协同优化。(239字)
|
8月前
|
数据采集 自然语言处理 搜索推荐
智能客服大模型微调:从基础模型到核心产品的全流程
本文详解电商智能客服大模型微调全流程:从需求分析、高质量数据准备(SFT+偏好数据),到ChatGLM-6B模型的LoRA监督微调与DPO对齐,再到RAG知识增强及FastAPI部署。附实操参数与效果评估标准,新手可快速复现。(239字)
|
安全 Cloud Native 容灾
海外泼天流量|浅谈全球化技术架构
本文对海外泼天流量现状做了快速整理,旨在抛砖引玉,促进国内企业在出海过程中,交流如何构建全球化技术架构的落地经验,相信会有越来越多资深人士分享更深层次的实践。
996 51
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
构建AI智能体:六十七、超参数如何影响大模型?通俗讲解原理、作用与实战示例
超参数是机器学习模型训练前需要人工设定的参数,它们控制着模型的学习过程而非直接通过学习获得。文章通过生动的类比(如自行车调整、烹饪配方)解释了超参数的概念,并详细介绍了其调优流程、常见类型(学习率、批量大小等)及对模型的影响。通过实际代码示例,展示了不同超参数设置如何影响模型训练效果,强调合理调优对提升模型性能、防止过拟合和优化资源使用的重要性。文章指出,超参数调优是模型成功的关键,初学者可从默认值开始逐步实验,借助网格搜索等工具实现高效调参。
881 105
|
7月前
|
存储 自然语言处理 API
省下亿万Token的秘密:三次对话,两万字代码背后的RAG魔法
本文剖析了开发者在调试中“复制粘贴海量代码→浪费Token→触发模型失忆”的恶性循环,提出RAG编码助手作为破局方案:通过AST智能切分、跨文件多跳检索与结构化Prompt,将每次输入从2.5万字压缩至数百字,Token消耗降低96%,响应提速数倍,且支持纯本地部署,兼顾效率、精准与安全。(239字)
737 6
|
存储 Kubernetes 调度
|
搜索推荐 Java 索引
java实现快速排序(详细解释代码和逻辑)
java实现快速排序(详细解释代码和逻辑)
|
人工智能 弹性计算 运维
亚太唯一!阿里云Serverless计算产品进入Forrester领导者象限
近日,Forrester发布《Serverless Development Platforms, Q2 2025》报告,阿里云函数计算FC与Serverless应用引擎SAE在21项评测中斩获9项最高分,成为国内唯一进入领导者象限的科技公司。
|
JSON JavaScript 数据格式
何如定义 JSON Schema 并验证该 json 数据?
本文定义了一个包含 audio 和 tags 两个必需属性的 JSON Schema,用于规范数据结构。其中,audio 是非空字符串,表示音频组件;tags 是非空数组,表示标签组件。通过示例数据和验证工具(如 ajv, NJsonSchema),可确保 JSON 数据符合 Schema 要求,从而保障数据的一致性和正确性。
756 1

热门文章

最新文章