问题
选第k小元素:特定分治策略
分析
1、 将数组中n个元素,按每5个一组,分成⌈n/5⌉组。
2、 将分好的⌈n/5⌉组排序之后从中取出每一组的中位数,用一个新的数组记录。
3、 用递归方法找出新数组中的中位数,即所有中位数中的中位数,将得到的中位数保存在m中,偶数个中位数取中间最小的。
4、 将原来的数组按m分割成两部分,设小于等于m的个数为S,大于m的个数为n-S。
5、 若index==k,则返回m;若index<k,继续在小于m的元素中递归查找第index小元素;若index>k,则继续在大于m的元素中递归查找第index-k小元素。
核心代码
// 找第K小元素
public static int smallestK(ArrayList<Integer> arr, int k) {
int bottom = 0;
int top = arr.size();
while (bottom < top) {
int i = 0;
int left = bottom;
int right = bottom;
int index = chooseMid(arr, bottom, top);
while (right < top) {
if (arr.get(right) < index) {
int temp = arr.get(left);
arr.set(left, arr.get(right));
arr.set(right, temp);
left++;
}
if (arr.get(right) == index) {
i = right;
}
right++;
}
arr.set(i, arr.get(left));
arr.set(left, index);
System.out.println(arr);
if (left + 1 < k) {
bottom = left + 1;
} else if (left + 1 > k) {
top = left;
} else {
return index;
}
}
return -1;
}