题目
给定一个长度为 的整数数列,以及一个整数 ,请用快速选择算法求出数列从小到大排序后的第 个数。
输入格式
第一行包含两个整数 和 。
第二行包含 个整数(所有整数均在 范围内),表示整数数列。
输出格式
输出一个整数,表示数列的第 小数。
数据范围
,
输入样例:
5 3
2 4 1 5 3
输出样例:
3
解题
方法一:快速选择
思路
快速排序在完成前两步:
- 找到分界点
p
(有三种选择:q[l]
、q[l + r >> 1]
、q[r]
)。 - 将区间 划分为两段,使得分界点左边所有数 ,分界点右边所有数 。
之后,会得到一个具有二段性的序列:
此时设序列分界点左边有 个元素,右边有 个元素,那么:
- 如果 ,递归 找第 小的数。
- 如果 ,递归 找第 小的数。
代码
import java.util.*;
import java.io.*;
public class Main {
static int[] nums;
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
int n = (int) in.nval;
in.nextToken();
int k = (int) in.nval;
nums = new int[n];
for (int i = 0; i < n; ++i) {
in.nextToken();
nums[i] = (int) in.nval;
}
System.out.println(quickSort(0, n - 1, k));
}
static int quickSort(int l, int r, int k) {
if (l == r) return nums[l];
int p = nums[l + r >> 1], i = l - 1, j = r + 1;
while (i < j) {
do ++i; while (nums[i] < p);
do --j; while (nums[j] > p);
if (i < j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
int sl = j - l + 1;
if (k <= sl) return quickSort(l, j, k);
return quickSort(j + 1, r, k - sl);
}
}
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, k;
int q[N];
int quick_sort(int q[], int l, int r, int k) {
if (l == r) return q[l];
int p = q[l + r >> 1], i = l - 1, j = r + 1;
while (i < j) {
do ++i; while (q[i] < p);
do --j; while (q[j] > p);
if (i < j) swap(q[i], q[j]);
}
int sl = j - l + 1;
if (k <= sl) return quick_sort(q, l, j, k);
return quick_sort(q, j + 1, r, k - sl);
}
int main () {
scanf("%d%d", &n, &k);
for (int i = 0; i < n; ++i) scanf("%d", &q[i]);
printf("%d", quick_sort(q, 0, n - 1, k));
return 0;
}
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, k, a[N];
int qsort(int l, int r) {
if (l >= r) return a[l];
int p = a[l + r >> 1], i = l - 1, j = r + 1;
while (i < j) {
while (a[++i] < p);
while (a[--j] > p);
if (i < j) swap(a[i], a[j]);
}
return k <= j ? qsort(l, j) : qsort(j + 1, r);
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
--k;
printf("%d\n", qsort(0, n - 1));
return 0;
}
时间复杂度:。
评论区