最小的K个数
题目描述:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
思路:堆排序中每趟可以输出最小元素,所以,借助堆排序可以得到最小的K个数。
步骤:
1 创建无元素的ArrayList对象。
2 如果数组为空或者k不是正整数,则返回指向ArrayList对象的引用。
3 获取数组容量。如果数组容量小于k,则返回指向ArrayList对象的引用;如果数组容量是1且k是1即结果只有1个元素,则把该元素添加到ArrayList对象中,返回指向ArrayList对象的引用。
4 构造初始小顶堆。
5 k趟获取当前最小元素,并把该元素添加到ArrayList对象中。
6 返回指向ArrayList对象的引用。
Java代码:
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int[] arr, int k) {
// 创建ArrayList对象
ArrayList<Integer> arrayList = new ArrayList<Integer>();
// 如果数组为空或者k不是正整数
if (arr == null || k <= 0) {
return arrayList;
}
// 获取数组容量
int len = arr.length;
// 如果数组容量小于k
// 如果数组容量是1且k是1即结果只有1个元素
if (len < k) {
return arrayList;
}
else if (len == 1 && k == 1) {
arrayList.add(arr[0]);
return arrayList;
}
// 设定可访问的最大下标
len--;
// 构造初始小顶堆
buildMinHeap(arr, len);
// k趟获取当前最小元素 数组下标从0开始
for (int i = len, low = len - k + 1; i >= low; i--) {
arrayList.add(arr[0]);
// 交换堆顶元素和堆底元素
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// 把剩余的i-1个元素建成堆
adjustDown(arr, 0, i - 1);
}
return arrayList;
}
// 构造初始小顶堆
private void buildMinHeap(int[] arr, int len) {
// 反复调整堆
for (int i = len / 2 - 1; i >= 0; i--) {
adjustDown(arr, i, len);
}
}
// 把当前结点所在的子树建成小顶堆
private void adjustDown(int[] arr, int parent, int len) {
// 暂存双亲结点值
int temp = arr[parent];
// 沿着较小的孩子结点向下筛选
for (int child = 2 * parent + 1; child <= len; child = 2 * child + 1) {
// 获取较小孩子结点的下标
if (child + 1 <= len && arr[child + 1] < arr[child]) {
child++;
}
// 筛选结束
if (temp <= arr[child]) {
break;
}
// 把孩子结点值赋到双亲结点上
arr[parent] = arr[child];
// 把孩子结点的下标赋给双亲结点
parent = child;
}
// 把双亲结点值放在最终位置上
arr[parent] = temp;
}
}
浙公网安备 33010602011771号