题目:
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入 4、5、1、6、2、7、3、8 这 8 个数字,则最小的 4 个数字是 1、2、3、4。
示例:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
输入:arr = [0,1,2,1], k = 1
输出:[0]
思考:
-
找到一个数组中最小的 k 个数,得出要对该数组进行排序
-
排序算法该如何选择呢?
-
根据题目要求,不要求输出的这 k 个数的顺序,考虑使用快速排序
-
因为是输出最小的 k 个数,索引从 0 开始,所以当基准数为 k+1 小的数时,这个基准数的左边子数组就是我们要找的 k 个数,也就是基准数索引为 k 时
-
使用快速排序划分子数组,每划分一次看基准数索引是否等于 k
-
若 k < 基准数索引 ,代表第 k+1 小的数字在 左子数组 中,则递归左子数组
-
若 k > 基准数索引 ,代表第 k+1 小的数字在 右子数组 中,则递归右子数组文章来源:https://www.toymoban.com/news/detail-637331.html
-
否则直接返回数组前 k 个数字文章来源地址https://www.toymoban.com/news/detail-637331.html
题解:
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (k >= arr.length) return arr;
return quickSort(arr, k, 0, arr.length-1);
}
private int[] quickSort(int[] arr, int k, int l, int r){
int i = l, j = r;
while (i<j){
while (i<j && arr[j] >= arr[l]) j--;
while (i<j && arr[i] <= arr[l]) i++;
swap(arr,i,j);
}
swap(arr,i,l);
//基准数索引 > k,递归左子数组
if (i > k) return quickSort(arr, k, l, i-1);
//基准数索引 < k,递归右子数组
if (i < k) return quickSort(arr, k, i+1, r);
return Arrays.copyOf(arr, k);
}
//交换方法
private void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
到了这里,关于【剑指 Offer 40】最小的k个数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!