2.Acwing基础课第786题-简单-第k个数
2.Acwing基础课第786题-简单-第k个数
题目描述
给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。
输入格式
第一行包含整数 n 和 k。
第二行包含 n 个整数(所有整数均在1~范围内),表示整个数列。
输出格式
输出一个整数,表示数列的第 k 小数。
数据范围
1≤n≤100000
输入样例
5 3
2 4 1 5 3
输出样例
3
思路解析:
算法:快速排序 ( Quick Sort )
时间复杂度:O(nlog(n))
解题思路:
1.使用快速排序,把数组从小到大进行排序
2.然后直接输出对应下标的数(记得减一)
代码:
快排
#include <iostream>
using namespace std;
const int N = 1e5+10;
int q[N];
int n, m;
void quick_sort(int q[], int l, int r)
{
if(l >= r) return;
int i = l-1, j = r+1, x = q[l+r>>1];
while(i < j)
{
do i++; while(q[i] < x);
do j--; while(q[j] > x);
if(i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j+1, r);
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++) cin >> q[i];
quick_sort(q, 0, n-1);
cout << q[m-1] << endl;
return 0;
}
选择
#include <iostream>
using namespace std;
// 定义数组最大长度:1e5+10 适配题目中常见的10万级数据规模
const int N = 1e5 + 10;
// n:数组元素个数,k:要找的第k小的元素
int n, k;
// q数组:存储待处理的整数序列
int q[N];
/**
* @brief 快速选择算法(Quick Select):在数组q的区间[l, r]中找到第k小的元素
* @param q 待处理的数组(全局数组也可,显式传参更规范)
* @param l 当前递归处理的区间左边界
* @param r 当前递归处理的区间右边界
* @param k 目标:找当前区间内第k小的元素
* @return int 找到的第k小的元素值
*/
int quick_sort(int q[], int l, int r, int k)
{
// 递归终止条件:当区间[l, r]只剩一个元素时,该元素就是当前区间要找的第k小元素
if (l >= r) return q[l];
// 初始化双指针:
// i = l-1 → 左指针初始在区间左边界左侧,后续向右移动
// j = r+1 → 右指针初始在区间右边界右侧,后续向左移动
// x = q[l+r>>1] → 取区间中间位置的元素作为基准值(避免有序数组导致算法退化)
int i = l - 1, j = r + 1, x = q[l + r >> 1];
// 双指针扫描区间,进行分区操作:把<=x的元素放到左区间,>=x的元素放到右区间
while (i < j)
{
// 左指针向右移动,直到找到第一个 >= x 的元素(跳过所有 < x 的元素)
do i++; while (q[i] < x);
// 右指针向左移动,直到找到第一个 <= x 的元素(跳过所有 > x 的元素)
do j--; while (q[j] > x);
// 如果两指针未相遇,交换这两个元素,保证左区间<=x,右区间>=x
if (i < j) swap(q[i], q[j]);
}
// 计算左分区[l, j]的元素个数(j - l + 1)
// 判断第k小的元素在左分区还是右分区:
if (k <= j - l + 1)
// 左分区元素数 >= k → 第k小在左分区,递归处理左分区[l, j]
return quick_sort(q, l, j, k);
else
// 左分区元素数 < k → 第k小在右分区,递归处理右分区[j+1, r]
// 且目标变为找右分区的第 (k - 左分区元素数) 小的元素
return quick_sort(q, j + 1, r, k - (j - l + 1));
}
int main()
{
// 输入:数组长度n + 要找的第k小元素
cin >> n >> k;
// 输入n个整数,存入q数组
for (int i = 0; i < n; i++) cin >> q[i];
// 调用快速选择函数,找q[0..n-1]中第k小的元素,并输出结果
cout << quick_sort(q, 0, n - 1, k) << endl;
return 0;
}

浙公网安备 33010602011771号