题目:给定一个乱序的数组,然后查找第 k 小的元素是什么?
思路:
在这里不讨论其他方法,运用快排的思想来解题。根据快速排序的思想,当我们找到基准值时,便可以确定这个值是位于第几个位置的元素,因此可以利用这一思路找第 k 小元素。在分成的其他两个区间中,用类似二分的方法只找其中一个区间即可。
其时间复杂度是O(n)
public class findKth {
public static void main(String[] args) {
int[] arr = {2,5,1,6,8,7,9,0}; //排序后: 0 1 2 5 6 7 8 9
int len = arr.length;
int k = 2;
int ans = findKthEle(arr, 0, len-1, k-1);
System.out.println(ans);
}
/**
* 查询数组arr中[i, j]区间的第 k 小
* @param arr
* @param l
* @param r
* @param k:排序后下标为 k 的值
* @return
*/
private static int findKthEle(int[] arr, int l, int r, int k) {
if(k < l || k > r) return Integer.MIN_VALUE; //不存在
if(l == r) return arr[r]; //只有一个时即为答案(不存在的情况已排除)
int i = l;
int j = r;
int key = arr[l];
while(i < j) {
while(i < j && arr[j] >= key)
j --;
while(i < j && arr[i] <= key)
i ++;
if(i < j)
swap(arr, i, j);
}
swap(arr, i, l);
// i 即为基准值的下标,此位置也是最终排序后的数组下标
if(i == k)
return arr[i];
else if(i > k)
return findKthEle(arr, l, i-1, k);
else
return findKthEle(arr, i+1, r, k);
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
如有错误或不合理的地方,敬请指正!
加油!!