这道题要做出来很容易,方法也有很多种,直接排序,大小顶堆都可以解决
我使用的是快排,然后做了一点小优化
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
quickSort(arr, 0, arr.length - 1, k - 1);
return Arrays.copyOf(arr, k);
}
private void quickSort(int[] arr, int start, int end, int k) {
if (start > end) {
return;
}
int i = start;
int j = end;
int temp = arr[start];
while (i < j) {
while (arr[j] >= temp && i < j) {
j--;
}
while (arr[i] <= temp && i < j) {
i++;
}
int a = arr[i];
arr[i] = arr[j];
arr[j] = a;
}
arr[start] = arr[i];
arr[i] = temp;
if (start <= k && k < j) {
quickSort(arr, start, i - 1, k);
} else if (k > i && k <= end) {
quickSort(arr, i + 1, end, k);
}
}
}
假设一次快排中i,j 相遇于点s
当k 位于 s的左侧时,我们只需要对左半部分进行排序,而不必考虑右半部分
当k=s 时,直接返回前k个元素就行了
当k位于s的右侧时,只需要对右半部分进行排序,而不必考虑左半部分
至于为什么,仔细思考一下不难得知