import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
//思路一、对数组进行排序 取前k个值
ArrayList<Integer> result = new ArrayList<>();
if(input == null || input.length == 0 || k == 0){
return result;
}
if(k >= input.length){
for(int i = 0;i<input.length;i++){
result.add(input[i]);
}
} else {
if(k == 1){
//直接寻找
int min = input[0];
for(int i = 1;i<input.length;i++){
if(input[i] < min){
min = input[i];
}
}
result.add(min);
} else {
//Arrays.sort(input);
//思路二、利用大根堆
heapSort(input,k);
for(int i = 0;i<k;i++){
result.add(input[i]);
}
}
}
return result;
}
private void heapSort(int[] input, int k){
//第一步 对前K个数进行原地建堆 采用自下而上的下滤方式建堆
//从第一个非叶子节点开始
int beginIndex = (k >> 1) - 1;
for(int i = beginIndex;i>=0;i--){
siftDown(i,input,k);
}
//第二步 遍历后续元素 只要是小于堆顶就交互 然后下坠
for(int i = k;i<input.length;i++){
if(input[i] < input[0]){
swap(input,i,0);
//交互完了 对堆顶执行下滤操作
siftDown(0,input,k);
}
}
}
private void siftDown(int i,int[] input, int k){
//当前点的值
int cur = input[i];
//如果小于左节点或者右节点就交互
int leftIndex = i * 2 + 1;
int rightIndex = leftIndex + 1;
int maxIndex = leftIndex;
//右节点不一定存在
if(rightIndex < k){
//右节点存在
if(input[leftIndex] < input[rightIndex]){
maxIndex = rightIndex;
}
}
if(cur < input[maxIndex]){
swap(input,i,maxIndex);
//交互完以后要继续判断是否还得下滤
int limitIndex = (k >> 1) - 1;
if(maxIndex <= limitIndex){
siftDown(maxIndex,input,k);
}
}
}
private void swap(int[] input,int index1,int index2){
int temp = input[index1];
input[index1] = input[index2];
input[index2] = temp;
}
}
题目链接:
最小的K个数