import java.util.Scanner;
/**
* 类似与求第k小的问题
* 求第k大相当于求第n-k+1小,n为数组长度
*
* 著名的BFPRT算法可保证在线性时间内得到结果。
* https://blog.csdn.net/qq_32767041/article/details/86099117
*
* 这里使用快速选择算法,这是一种基于快速排序的算法,
* 在实现上比BFPRT更简单。
* https://blog.csdn.net/qq_32767041/article/details/86300744
*
* @author wylu
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String[] strs = scanner.nextLine().split(" ");
int[] arr = new int[strs.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.valueOf(strs[i]);
}
int k = scanner.nextInt();
System.out.println(arr[quickSelect(arr, arr.length - k + 1)]);
}
}
/**
* 查找第k小元素
* @param arr 无序数组
* @param k 目标第k小
* @return 成功:返回第k小元素的索引
* 失败:返回-1
*/
public static int quickSelect(int[] arr, int k) {
int left = 0, right = arr.length - 1, idx;
while (left <= right) {
idx = partition(arr, left, right);
if ((k - 1) == idx) return idx;
else if ((k - 1) > idx) left = idx + 1;
else right = idx - 1;
}
return -1;
}
/**
* 对给定的数组区间进行划分
* @param arr 数组
* @param left 区间下限,包含arr[left]
* @param right 区间上限,包含arr[right]
* @return 返回划分后,划分基准的索引
*/
private static int partition(int[] arr, int left, int right) {
int j = left - 1;
for (int i = left; i < right; i++) {
if (arr[i] <= arr[right]) swap(arr, i, ++j);
}
swap(arr, ++j, right);
return j;
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
355




被折叠的 条评论
为什么被折叠?



