目录
最小的k个数
描述
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例 1
输入
arr = [3,2,1], k = 2
输出
[1,2] 或者 [2,1]
示例 2
输入
arr = [0,1,2,1], k = 1
输出
[0]
限制
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000
方法一:排序后输出
我们可以先将数组都按照从小到大排序好,然后输出前k个数即可,这里我们用快排的方法。
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
int[] res=new int[k];
arr=QuickSort(arr,0,arr.length-1);
for (int i = 0; i < k; i++) {
res[i]=arr[i];
}
return res;
}
public int[] QuickSort(int[] arr,int low,int high){
if (low<high){
int curPos=Partition(arr,low,high);
QuickSort(arr,low,curPos-1);
QuickSort(arr,curPos+1,high);
}
return arr;
}
public int Partition(int[] arr, int low, int high) {
int curPos = low;
int curVal = arr[low];
for (int i = low; i <= high; i++) {
if (arr[i] < curVal) {
curPos++;
if (i != curPos) {
int temp=arr[i];
arr[i]=arr[curPos];
arr[curPos]=temp;
}
}
}
arr[low]=arr[curPos];
arr[curPos]=curVal;
return curPos;
}
}
方法二:快速排序改进
针对本题,只需要输出k个最小的数,并不需要这些数有序,所以我们可以获得快速排序中首元素在数组中的位置,如果这个位置刚好是第k+1个,那么它左边就刚好是最小的k个数,而不需要对右边进行排序。
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if (k >= arr.length) return arr;
return QuickSort(arr, 0, arr.length - 1, k);
}
public int[] QuickSort(int[] arr,int low,int high,int k){
int curPos = Partition(arr, low, high);
if(curPos>k) return QuickSort(arr, low, curPos - 1,k);//往左边继续排序
if(curPos<k) return QuickSort(arr, curPos + 1, high,k);//往右边继续排序
return Arrays.copyOf(arr,k);//若此时i==k,则拷贝前k个数
}
public int Partition(int[] arr, int low, int high) {
int curPos = low;
int curVal = arr[low];
for (int i = low; i <= high; i++) {
if (arr[i] < curVal) {
curPos++;
if (i != curPos) {
int temp=arr[i];
arr[i]=arr[curPos];
arr[curPos]=temp;
}
}
}
arr[low]=arr[curPos];
arr[curPos]=curVal;
return curPos;
}
}