题目描述:
标签:数组 分治 快速选择 排序 堆(优先队列)
输入整数数组
arr
,找出其中最小的k
个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
代码:
《方法一:快速排序》
思路分析:
利用快排思想,找到第k-1个位置的下标,然后利用Arrays.copyOf(arr, index+1)用来返回(0~index)的元素。
import java.util.Random;
class Solution {
private static Random random = new Random(System.currentTimeMillis());
public int[] getLeastNumbers(int[] arr, int k) {
if(k == 0 || arr.length == 0){
return new int[0];
}
int left = 0;
int right = arr.length - 1;
while(true){
int index = partition(arr, left, right);
if(index == k - 1){
return Arrays.copyOf(arr, index + 1);
}else if(index < k){
left = index + 1;
}else{
right = index - 1;
}
}
}
public int partition(int[] arr, int left, int right){
if(right > left){
int randomIndex = left + 1 + random.nextInt(right - left);
swap(arr, left, randomIndex);
}
int privot = arr[left];
int j = left;
for(int i = left + 1;i <= right;i++){
if(arr[i] < privot){
j++;
swap(arr, i, j);
}
}
swap(arr, left, j);
return j;
}
public void swap(int[] arr, int index1, int index2){
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
}
《方法二:堆排序》
思路分析:
使用了java的优先队列API来构建大顶堆,每次加入元素offer会自动构成大顶堆,当发现堆的元素大小大于k时,就要把堆顶的元素poll出来。
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
if(k == 0 || arr.length == 0){
return new int[0];
}
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((o1,o2) -> o2 - o1);
for(int num : arr){
maxHeap.offer(num);
if(maxHeap.size() > k){
maxHeap.poll();
}
}
int[] res = new int[maxHeap.size()];
int j = 0;
for (int e : maxHeap) {
res[j++] = e;
}
return res;
}
}