寻找区间内第k小的数
sort排序
这是最直接暴力的方法,时间复杂度为
直接排序,输出第k小的值即可
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n, k;
int a[N];
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; ++ i) cin >> a[i];
sort(a + 1, a + n + 1);
cout << a[k] << endl;
return 0;
}
快速选择算法
时间复杂度的计算主要关注左右两个指针的移动,总次数为,所以时间复杂度为
具体内容请见快速排序引申出的快速选择算法
大根堆
因为需要遍历每个元素,且每个元素插入堆中的复杂度为,所以时间复杂度为,实际使用应该用不到,这里只是记录一种思想
本以为可以使用对顶堆解决这个问题,但是搞错了对顶堆的应用场景,然后误打误撞的发现大根堆也可以解决
假设寻找的为第k小的数,遍历所有数,将小于堆顶的数据插入堆,并始终维护堆的大小为k,最终堆顶元素即为第k小的数
我总是担心更小的数据会将目标元素提前弹出堆,但这种情况是不会发生的,假设能够发生这种情况,那么说明被弹出的目标元素在升序序列中是第k位之前的,所以才会因为堆满而被弹出。因为目标元素就是第k小的,所以我们的假设错误。因为没有进入堆的元素在有序序列中均是第k位之后的,所以最终堆顶元素就是有序序列中前k位元素最大的元素,即第k小的元素
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1e5 + 10;
int n, k;
int a[N];
int kth_element(int a[], int l, int r, int k)
{
priority_queue<int> down; // 大根堆
for (int i = l; i <= r; ++ i)
{
if (down.empty() || a[i] < down.top()) down.push(a[i]);
if (down.size() > k) down.pop();
}
return down.top();
}
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; ++ i) cin >> a[i];
cout << kth_element(a, 1, n, k) << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理