【TopK问题】——用堆实现

news/2024/5/20 7:57:19 标签: 算法, 深度优先, TOPK问题,

文章目录

  • 一、TopK问题是什么
  • 二、解决方法
  • 三、时间复杂度

一、TopK问题是什么

TopK问题就是从1000个数中找出前K个最大的数或者最小的数这样的类似问题。

不过并不要求这k个数字必须是有序的,如果题目有要求,则进行排序即可。

还有比如求出全国玩韩信前十名等等,排出班级前十名也是TopK问题。

二、解决方法

采用的方式可以较快解决。

思路:如果需要排前k个最大的数,则需要建一个小
如果需要排前k个最小的数,则需要建一个大

假设现在需要排序前k个最大的数,则需要建立一个小
建立小是拿n个数的前k个数来建立的。

不能把n个数全部建立成一个小,这样效率会大打折扣,因为通过向下调整建的时间复杂度是O(N),假如要从10亿个数字中排前50个最大的,那么建立一个10亿个数大小的,开销还是比较大的。

建立了一个小后,此时顶元素是最小的,
从第k+1个数开始,只要第K+1个数大于顶元素,就将该数字于顶元素进行交换,然后再向下调整。

这样做的结果是:只要我比顶元素大,我就进,如果我在中是比较大的,我就会“下沉”到底,(因为这是一个小)。
这样遍历多次后,原来中的元素会被换成新的一批更大一点的元素。

当我们遍历完n个数后,留在中的一定是前k个最大的数。

代码如下:
随机生成10个1000以内的数字,求这10个数字的最大的3个:

void Find_TopK(int* a, int n ,int k)
{
	assert(a!=NULL);
	assert(k > 0);

	int* topk = (int*)malloc(sizeof(int) * k);
	assert(topk);
	for (int i = 0; i < k; ++i)
	{
		topk[i] = a[i];
	}

	//1.先建,向下调整建,现在是建小,那就找最大的前k个
	//把前k个抓起来,建立一个k大小的

	for (int i = (k - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(topk, k, i);
	}

	//2.然后从第k个开始,往里面插入
	int j = k;
	while (j < n)
	{
		if (a[j] > topk[0])
		{
			topk[0] = a[j];
			AdjustDown(topk, k, 0);
		}
		j++;
	}

	printf("这10个数中最大的3个数为:\n");
	for (int i = 0; i < k; ++i)
	{
		printf("%d ", topk[i]);
	}

	free(topk);
	topk = NULL;
}

int main()
{
	srand(time(0));
	int a[100] = { 0 };
	printf("随机生成的10个1000以内的数为:\n");
	for (int i = 0; i < 10; ++i)
	{
		a[i] = rand() % 1000;
		printf("%d ", a[i]);
	}
	printf("\n");
	int k = 3;

	int n = sizeof(a) / sizeof(a[0]);
	Find_TopK(a,n,k);
	return 0;
}

三、时间复杂度

的时间复杂度:O(K)
遍历的时间复杂度:O(N-K)
每次遍历调整的时间复杂度:O(logK)
总的时间复杂度O(K+(N-K)logK) ≈ O(NlogK)


http://www.niftyadmin.cn/n/187666.html

相关文章

Qt C++与Python混合编程:补充错误

在提示中&#xff0c;需要引用Python.h&#xff0c;出现错误。 1、找不到Python.h 如果是pro工程&#xff0c;需要在里面配置&#xff1b; INCLUDEPATH /Users/xinnianwang/opt/anaconda3/include LIBS /Users/xinnianwang/opt/anaconda3/lib 如果是CMakeLists.txt需要配…

第三章 Vite4+Vue3+Vtkjs 封装工具让其支持加载各种格式的模型

一、介绍 😋 😋 😋 vtk.js目前支持的格式有vtp、vti、skybox、obj、obz、stl、ply、gltf 、glb、x3d、3ds、fbx、dae、json、glyph等等。vtk.js还支持从JavaScript数组、Typed Arrays和ImageData对象中创建数据集。支持这么多格式是因为vtk.js本身就给我们提供了相应的R…

编码器5V差分信号隔离转换脉冲信号0-24V或集电极开路输出

主要特性:>> 编码器差分信号直接输入转换成脉冲信号>> 支持A、B和Z三相差分同时转换>> 3路输入&#xff0c;3路输出&#xff0c;输出脉冲幅值可选>> 不改变原波形频率&#xff0c;响应速度500KHz以上>> 电源、信号输入、信号输出 3000VDC三隔离&…

华中师范大学研究生学位论文规范及排版技巧

研究生学位论文规范研究生学位论文是学位申请者获取博士、硕士学位的重要依据&#xff0c;是研究生科研能力、科研成果的集中体现&#xff0c;同时也是重要的社会文献资料。为了规范学位论文撰写&#xff0c;提高我校研究生学位论文质量&#xff0c;根据GB/T7713-1987《科学技术…

立体声骨传导蓝牙耳机哪款好一点,分享几款优秀的骨传导耳机

随着蓝牙耳机的不断发展&#xff0c;蓝牙耳机已经成为了我们日常生活中使用最多的一款无线蓝牙耳机。而在近几年有一种新型的骨传导耳机诞生&#xff0c;但有不少人认为骨传导耳机就是一种噱头。其实不然&#xff0c;骨传导耳机其实是一种革命性的产品。它通过把声音转化为不同…

蓝桥杯之python基础

蓝桥杯之python基础一.问题与学习二、python基础的关键知识点2.1 Python 标识符2.2 行和缩进2.3 多行语句2.4 python引号2.5 python注释2.6 python空行2.7 等待用户输入2.8 同一行显示多条语句2.9 print()输出2.10 多个语句构成代码组三、python变量类型/标准数据类型3.1 变量赋…

[WPF] 集合元素数据绑定与模板

在我们的应用程序里面, 很多时候会用到列表, 而列表元素的样式, 我们是希望能够自定义的, 根据 MVVM 设计模式, 我们的列表元素, 也需要绑定到后台数据, 这样后台数据进行更新的时候, 前台 UI 也会跟着更新, 包括元素也会自动增删. 使用 ItemsControl ItemsControl 是最基本的…

CVPR无监督/自监督学习(Un/Self-supervised Learning)方向论文学习(附摘要)

目录 2022CVPR UniVIP: A Unified Framework for Self-Supervised Visual Pre-training&#xff08;自监督学习&#xff09; Crafting Better Contrastive Views for Siamese Representation Learning&#xff08;自监督学习&#xff09; HCSC: Hierarchical Contrastive S…