选第k小元素:特定分治策略(JAVA)
问题
在一个数组S中查找第k小的元素并输出。
解析
以S中的某个元素m作为划分标准,将S划分为两个子数组S1和S2,把这个数组中比m小的都放入S1的数组中,数组S1的元素个数是|S1|个;把这个数组中比m*大的都放入S2的数组中,数组S2的元素个数是|S2|个。
- 若k<|S1|,则原问题归纳为在数组S1中找第k小的子问题。
- 若k=|S1|+1,则m*就是要找的第k小元素。
- 若k>|S1|+1,则原问题归纳为在数组S2中找第n−|S1|−1小的子问题。
或者说下面这个图:
设计
将输入的数据按照4个一组分为多组,选取这几个组的中位数,然后选择这N个中位数中的中位数作为mid,然后将输入的数据与mid值进行比较,如果小于mid数,就放入S1中,如果比mid大的话就放入S2中,最后根据S1,S2的长度与k进行比较,分为3种情况进行比较。核心代码如下;
private static int select(int[] A, int low, int high, int k) {
int num = high - low + 1;
int group = (int) Math.ceil(1.0 * num / r