当前位置: 首页 > article >正文

第k小(经典Top k问题)

题目描述:

有一个长度为n的数组,值为 a[i], 牛牛想找到数组中第 k 小的数。比如 1 2 2 3 4  6 中,第 3 小的数就是2.

牛牛觉得这个游戏太简单了,想加一点难度,现在牛牛有 m 个操作,每个操作有两种类型。

1 x  1 代表操作一,给数组中加一个元素 x 。(0 ≤ x ≤ 1e9)

2     2 代表操作二,查询第 k 小的数。如果没有 k 个数就输出−1

输入描述:

第一行有三个整数,n m k,(1≤n,m,k≤2e5)

第二行包含 n 个整数 a[i] ( 0 ≤ a[i] ≤ 1e9)

接下来m行,每行代表一个操作。具体见题目描述

输出描述:

每次查询输出一个第 k 小的数。

示例1

输入

5 4 3 1 2 3 4 5 2 1 1 1 3 2

5 4 3
1 2 3 4 5
2
1 1
1 3
2

输出

3 2

3
2

解题思路: 

这是一道经典的 topk 问题,要求最小的第k个数或者最大的第k的数。通常我们会采用堆的形式来解决此类问题。如果我们要求最小的第k个数,那么我们就要建大根堆(从上到下逐渐减少)。将k个数据push到堆中,堆会按照由大到小的堆数据。一旦超过k个数据,就将堆顶出堆,这样就保证了堆顶是第k小(一次进一个,每次出最大)。同理可得,第k大也是同样的道理。该题的建堆时间复杂度为O(k),排序的时间复杂度为O(k logn)。

代码样例:

#include <iostream>
#include <queue>
using namespace std;

int n, m, k;
priority_queue<int> heap;
int op;

int main()
{
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++)
	{
		int x; cin >> x;
		heap.push(x);//默认大根堆
		if (heap.size() > k)
		{
			heap.pop();
		}
	}
	while (m--)
	{
		cin >> op;
		if (op == 1)
		{
			int x; cin >> x;
			heap.push(x);
			if (heap.size() > k)
			{
				heap.pop();
			}
		}
		else
		{
			if (heap.size() >= k)
			{
				cout << heap.top() << endl;
			}
			else
			{
				cout << "-1" << endl;
			}
		}
	}
	return 0;
}

题目链接:

第 k 小https://ac.nowcoder.com/acm/problem/214362


http://www.kler.cn/a/509155.html

相关文章:

  • 4.Spring AI Prompt:与大模型进行有效沟通
  • 在.NET用C#将Word文档转换为HTML格式
  • python如何解析word文件格式(.docx)
  • 技术晋升读书笔记—华为研发
  • 从玩具到工业控制--51单片机的跨界传奇【3】
  • 单元测试与unittest框架
  • springboot整合libreoffice(两种方式,使用本地和远程的libreoffice);docker中同时部署应用和libreoffice
  • Vector的模拟实现与迭代器失效问题
  • 什么是SSL及SSL的工作流程
  • 线性表代码实战
  • 开发完全开源的AI会议助手:提升会议效率
  • STM32的DMA作用
  • Ubuntu20.04安装mysql9.0.1,并且修改数据文件路径
  • 【C++】哈希表的使用
  • Solidity03 Solidity变量简述
  • SpringBoot的AOP-入门
  • nvm 管理nodejs,安装pnpm后报错,出现:pnpm不是内部或外部命令,也不是可运行的程序或批处理文件。
  • Plume :RWAfi 叙事引领者,全新加密时代的新蓝筹生态
  • 第4章 Kafka核心API——Kafka客户端操作
  • 深度学习常见术语解释
  • 计算机网络ENSP课设--三层架构企业网络
  • 后盾人JS -- JS数组挖掘(成年篇)
  • Mysql--实战篇--连接池(连接池原理,HikariCP、C3P0、Druid和DBCP等)
  • LLama 架构一览
  • QT的TCP通讯
  • PG 和 mysql 区别