利用分桶、堆与多路归并解决 TopK 问题:结果处理阶段解析

在处理大规模数据时,TopK 问题是一个常见且具有挑战性的任务,即从海量数据中找出最大(或最小)的 K 个元素。为了高效地解决这个问题,我们可以采用分桶、堆和多路归并相结合的方法。本文将详细剖析该方法中结果处理阶段的代码逻辑。

问题背景

TopK 问题在数据处理、搜索引擎、推荐系统等领域都有广泛的应用。为了高效解决该问题,我们采用了分桶、堆和多路归并的策略。具体步骤包括:首先将数据分桶,降低数据规模;然后在每个桶中使用最小堆找出局部的 TopK 元素;最后将每个桶的 TopK 元素合并到全局最小堆中

具体代码

`import java.util.*;

public class TopKSolution {

    public static List<Integer> topK(int[] nums, int k) {
// 步骤 1: 分桶
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int num : nums) {
min = Math.min(min, num);
max = Math.max(max, num);
}
// 桶的数量
int bucketSize = 10;
int bucketCount = (max - min) / bucketSize + 1;
List<List<Integer>> buckets = new ArrayList<>();
for (int i = 0; i < bucketCount; i++) {
buckets.add(new ArrayList<>());
}
// 将元素放入对应的桶中
for (int num : nums) {
int bucketIndex = (num - min) / bucketSize;
buckets.get(bucketIndex).add(num);
} // 步骤 2: 每个桶中使用最小堆找出 TopK
PriorityQueue<Integer> globalHeap = new PriorityQueue<>(k);
for (List<Integer> bucket : buckets) {
if (bucket.isEmpty()) continue;
// 为当前桶创建一个容量为 k 的最小堆,用于找出该桶内的 TopK 元素
PriorityQueue<Integer> localHeap = new PriorityQueue<>(k, Comparator.naturalOrder());
for (int num : bucket) {
if (localHeap.size() < k) {
localHeap.offer(num);
} else if (num > localHeap.peek()) {
localHeap.poll();
localHeap.offer(num);
}
}
// 将每个桶的 TopK 元素合并到全局堆中
for (int num : localHeap) {
if (globalHeap.size() < k) {
globalHeap.offer(num);
} else if (num > globalHeap.peek()) {
globalHeap.poll();
globalHeap.offer(num);
}
}
} // 步骤 3: 结果处理
List<Integer> result = new ArrayList<>(globalHeap);
result.sort(Collections.reverseOrder());
return result;
} public static void main(String[] args) {
int[] nums = {3, 2, 1, 5, 6, 4};
int k = 2;
List<Integer> topK = topK(nums, k);
System.out.println("Top " + k + " elements: " + topK);
}
} `

代码解释

分桶:

  1. 先找出数组里的最小值 min 和最大值 max。
  2. 确定桶的数量 bucketCount,这里每个桶的大小为 bucketSize。
  3. 把数组中的每个元素依据其值放入对应的桶中。

堆:

  1. 针对每个桶,使用最小堆 localHeap 找出该桶内的 TopK 元素。
  2. 要是堆的大小小于 K,就直接将元素加入堆;若堆的大小已达到 K 且当前元素比堆顶元素大,就移除堆顶元素并将当前元素加入堆。

多路归并:

  1. 把每个桶的 TopK 元素合并到全局最小堆 globalHeap 中。
  2. 最终从全局堆中获取最大的 K 个元素。

结果处理:

  1. 把全局堆中的元素存到列表里,然后按降序排序。

大量数据topk-分桶+堆+多路并归解决方案的更多相关文章

  1. 入门大数据---Hive分区表和分桶表

    一.分区表 1.1 概念 Hive 中的表对应为 HDFS 上的指定目录,在查询数据时候,默认会对全表进行扫描,这样时间和性能的消耗都非常大. 分区为 HDFS 上表目录的子目录,数据按照分区存储在子 ...

  2. 大数据学习----day27----hive02------1. 分桶表以及分桶抽样查询 2. 导出数据 3.Hive数据类型 4 逐行运算查询基本语法(group by用法,原理补充) 5.case when(练习题,多表关联)6 排序

    1. 分桶表以及分桶抽样查询 1.1 分桶表 对Hive(Inceptor)表分桶可以将表中记录按分桶键(某个字段对应的的值)的哈希值分散进多个文件中,这些小文件称为桶. 如要按照name属性分为3个 ...

  3. HIVE—索引、分区和分桶的区别

    一.索引 简介 Hive支持索引,但是Hive的索引与关系型数据库中的索引并不相同,比如,Hive不支持主键或者外键. Hive索引可以建立在表中的某些列上,以提升一些操作的效率,例如减少MapRed ...

  4. Hive 学习之路(五)—— Hive 分区表和分桶表

    一.分区表 1.1 概念 Hive中的表对应为HDFS上的指定目录,在查询数据时候,默认会对全表进行扫描,这样时间和性能的消耗都非常大. 分区为HDFS上表目录的子目录,数据按照分区存储在子目录中.如 ...

  5. Hive入门(三)分桶

    1 什么是分桶 上一篇说到了分区,分区中的数据可以被进一步拆分成桶,bucket.不同于分区对列直接进行拆分,桶往往使用列的哈希值进行数据采样.在分区数量过于庞大以至于可能导致文件系统崩溃时,建议使用 ...

  6. Hive 系列(五)—— Hive 分区表和分桶表

    一.分区表 1.1 概念 Hive 中的表对应为 HDFS 上的指定目录,在查询数据时候,默认会对全表进行扫描,这样时间和性能的消耗都非常大. 分区为 HDFS 上表目录的子目录,数据按照分区存储在子 ...

  7. Hive 教程(四)-分区表与分桶表

    在 hive 中分区表是很常用的,分桶表可能没那么常用,本文主讲分区表. 概念 分区表 在 hive 中,表是可以分区的,hive 表的每个区其实是对应 hdfs 上的一个文件夹: 可以通过多层文件夹 ...

  8. hive 分桶及抽样调查

    1.分桶的概述 分区提供了一个隔离数据和优化查询的遍历方式.不是所有的数据集都可形成合力的分区 对于一张表或者分区,hive可以进一步组织成桶,也就是更为细粒度的数据范围 分区针对的是数据的存储路径( ...

  9. Hive的分桶表

    [分桶概述] Hive表分区的实质是分目录(将超大表的数据按指定标准细分到指定目录),且分区的字段不属于Hive表中存在的字段:分桶的实质是分文件(将超大文件的数据按指定标准细分到分桶文件),且分桶的 ...

  10. Hive(六)【分区表、分桶表】

    目录 一.分区表 1.本质 2.创建分区表 3.加载数据到分区表 4.查看分区 5.增加分区 6.删除分区 7.二级分区 8.分区表和元数据对应得三种方式 9.动态分区 二.分桶表 1.创建分桶表 2 ...

随机推荐

  1. 创建企业级地理数据库——PostgreSQL版

    创建PostgreSQL空间数据库 填写相应的参数,选择授权文件 报错 默认安装postgresql后,执行以上操作报错 "You must copy the latest ST_GEOME ...

  2. RPC简介及框架选择-copy

    简单介绍RPC协议及常见框架,对比传统restful api和RPC方式的优缺点.常见RPC框架,gRPC及序列化方式Protobuf等 HTTP协议 http协议是基于tcp协议的,tcp协议是流式 ...

  3. 学Shiro完结版-5

    第二十一章 授予身份及切换身份--<跟我学Shiro> 在一些场景中,比如某个领导因为一些原因不能进行登录网站进行一些操作,他想把他网站上的工作委托给他的秘书,但是他不想把帐号/密码告诉他 ...

  4. MySQL5.7x 主从复制

    原文链接:https://blog.liuzijian.com/post/9f8ede8e-26de-75d6-6347.html 在MySQL中,主从复制(Master-Slave Replicat ...

  5. Node.js 中 mysql 事务的写法

    最近做一个公司内部的信息化平台,本着短平快,选择了 Nodejs + Express + Vue + mysql/mongodb 的技术路线. 该写法主要利用了递归,下面把事务的写法记录一下,做了简单 ...

  6. TiDB体系架构

    本文分享自天翼云开发者社区<TiDB体系架构>,作者:x****n 如图所示,TiDB体系中三大组成部分:PD.TiDB Server.TiKV 1.PD:负责产生全局的TSO时间.控制R ...

  7. 利用Python开发Exporter,集成Prometheus和Grafana对进程监控

    利用Python开发Exporter,集成Prometheus和Grafana对进程监控 在现代软件开发和运维中,监控是确保系统稳定运行和快速响应问题的重要手段.Prometheus和Grafana的 ...

  8. NLLB 与 ChatGPT 双向优化:探索翻译模型与语言模型在小语种应用的融合策略

    作者:来自 vivo 互联网算法团队- Huang Minghui 本文探讨了 NLLB 翻译模型与 ChatGPT 在小语种应用中的双向优化策略.首先介绍了 NLLB-200 的背景.数据.分词器和 ...

  9. 无分类有tag

    1 2

  10. (抄自己luogu上的博客)莫队总结

    虽然当时文风很2,但是觉得写的蛮好的,就在这里贴一下吧. 最近学了分块(太难想了 \(qwq\) )和莫队(太神奇了 \(0w0\) ),写一个阶段性总结~ 分块 总所周知,分块是一种神奇的暴力,用 ...