问题描述:
给定一个无序的数组,从一个数组中找出第k个最小的数,例如,数组{ 1,5,2,6,8,0,6 }, 其中第4小的数为5
思路分析:
方法一:排序法
最数组进行排序,排序后的第k-1个位置上的数字即为数组的第k个最小的数,时间复杂度为O(nlogn)
方法二:剪枝法
采用快速排序的思想来实现。选一个数 tmp = a[n-1] 作为枢纽, 把比他小的数都放在他的左边,比他大的数放在他的右边,然后判断tmp的位置,
如果他的位置 == k-1, 那么它就是第k个最小的数;
如果它的位置 < k-1, 那么第k个小的元素一定在数组的右半部分, 采用递归的方法在数组的右半部分继续查找;
如果它的位置 > k-1, 那么第k个小的元素一定在数组的左半部分, 采用递归的方法在数组的左半部分继续查找;
代码:
private int getKMin(int[] a, int k) {
if(a == null || a.length<k){
return Integer.MIN_VALUE;
}
return quikSort(a,0,a.length-1,k);
}
private int quikSort(int[] a, int low, int high, int k) {
// 第0个元素作为枢纽
int i = low;
int j=high;
int tmp = a[i];
if(low > high){
return Integer.MIN_VALUE;
}
// 快速排序
while(i<j){
while(i<j && a[j]>=tmp){
j--;
}
if(i<j){
a[i++] = a[j];
}
while(i<j && a[i]<tmp){
i++;
}
if(i<j){
a[j--] = a[i];
}
}//
a[i] = tmp;
// 判断i+1与k的大小
if(i+1 == k){
return tmp;
}else if(i+1 > k){
return quikSort(a, low, i-1, k);
}else{
return quikSort(a, i+1, high, k);
}
}
测试代码:
@Test
public void test1(){
int[] a = {1,5,2,6,8,0,6};
int kmin = getKMin(a,4);
System.out.print(kmin);
}