给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。 输入格式 第一行包含两个整数 n 和 k。 第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整数数列。 输出格式 输出一个整数,表示数列的第 k 小数。 数据范围 1≤n≤100000, 1≤k≤n 输入样例: 5 3 2 4 1 5 3 输出样例: 3
这是快排变题,先看一手快排的模板
import java.util.*;
public class Main{
public static void main (String args[]){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int [] a = new int [n];
for(int i = 0; i < n; i++)a[i] = sc.nextInt();
quickSort(a,0,n-1);
for(int i = 0; i < n;i++ )System.out.print(a[i] + " ");
}
public static void quickSort(int [] a,int l, int r){
if(l >= r) return;
int i = l - 1, j = r + 1, x = a [l+r>> 1];
while(i < j){
do i ++;while(a[i] < x);
do j --;while(a[j] > x);
if( i < j){
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
quickSort(a,l,j);
quickSort(a,j+1,r);
}
}这题在递归的时候不需要递归两边处理
- 当左边sl <= k 时 递归左边即可
- 当 sl > k 时,递归右边即可,但此时的k = k - sl
ac code
import java.util.*;
public class Main{
static int[] a;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
a = new int[n];
for(int i = 0; i < n; i++)a[i] = sc.nextInt();
System.out.println(quickSort(0, n - 1, k));
}
public static int quickSort(int l,int r,int k){
if(l == r)return a[l];
int x = a[l + r >> 1],i = l - 1,j = r + 1;
while(i < j){
while(a[++ i] < x);
while(a[-- j] > x);
if(i < j){
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
int sl = j - l + 1;
if(k <= sl)return quickSort(l,j,k);
return quickSort(j + 1,r, k - sl);
}
}空间复杂度o(n),
时间复杂度 n + n/2 + n/4 + n / 8 ... ≈2n ,∴o(n)。

京公网安备 11010502036488号