题目描述
题干:
设计一个算法,找出数组中最小的k个数。以任意顺序返回这k个数均可。
示例:
输入: arr = [1,3,5,7,2,4,6,8], k = 4
输出: [1,2,3,4]
题解思路
返回数组中的前k个,首先想都不要想直接就是排序返回前k个直接解决
不过既然是面试题,我们就多想几个办法吧,只要是返回最大或者最小的元素
我们可以借助堆结构来实现,这里给出最小堆的写法,官方题解给出的最大堆的显得有些啰嗦
如果还要优化,当然那就是从排序算法上继续做文章,自己写快排算法进行排序会更快
正确代码
// 排序
public int[] smallestK(int[] arr, int k) {
int[] ans = new int[k];
Arrays.sort(arr);
for (int i = 0; i < k; i++) {
ans[i] = arr[i];
}
return ans;
}
// 最小堆
public int[] smallestK01(int[] arr, int k) {
int[] vec = new int[k];
if (k == 0) {
return vec;
}
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
for (int i : arr) {
queue.offer(i);
}
for (int i = 0; i < vec.length; i++) {
vec[i] = queue.poll();
}
return vec;
}
// 大顶堆
public int[] smallestK2(int[] arr, int k) {
int[] vec = new int[k];
if (k == 0) { // 排除 0 的情况
return vec;
}
PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
public int compare(Integer num1, Integer num2) {
return num2 - num1;
}
});
for (int i = 0; i < k; ++i) {
queue.offer(arr[i]);
}
for (int i = k; i < arr.length; ++i) {
if (queue.peek() > arr[i]) {
queue.poll();
queue.offer(arr[i]);
}
}
for (int i = 0; i < k; ++i) {
vec[i] = queue.poll();
}
return vec;
}
总结
这里要说一说Arrays中的sort方法,它内部采用的排序算法根据长度而定
如果排序元素在47之下则用插入排序,在47到268之间用快速排序
再多的话就用归并排序的方法,但是具体细节还和传统的这些算法不同,增加了细节
如果文章存在问题或者有更好的题解,欢迎再评论区斧正和评论,各自努力,你我最高处见
LeetCode——面试题 17.14. 最小K个数(Java)