import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> res = new ArrayList<>();
if (input == null || input.length == 0 || k == 0) {
return res;
}
if (k == 1) {
//直接查找
int target = input[0];
for (int i = 1; i < input.length; i++) {
if (input[i] < target) {
target = input[i];
}
}
res.add(target);
return res;
}
//特殊情况处理完毕 开始处理正常情况
//第一步 对前k个数进行原地建堆 采用大顶堆
int index = (k >> 1) - 1;
for (int i = index; i >= 0; i--) {
siftDown(input, i, k);
}
//第二步 不断从剩余的数中比大顶堆顶部小的数 替换进堆中
for (int i = k; i < input.length; i++) {
if (input[i] < input[0]) {
swap(input, 0, i);
siftDown(input, 0, k);
}
}
//第3步 对前K个数进行快速排序
quickSort(input, 0, k - 1);
//第4步 将前K个数 就是堆中的数据 放入集合返回
for (int i = 0; i < k; i++) {
res.add(input[i]);
}
return res;
}
private void siftDown(int[] arr, int index, int length) {
int limitIndex = (length >> 1) - 1;
if (index > limitIndex) {
return;
}
int left = index * 2 + 1;
int right = left + 1;
int maxIndex = left;
if (right < length) {
maxIndex = arr[left] >= arr[right] ? left : right;
}
if (arr[maxIndex] > arr[index]) {
swap(arr, maxIndex, index);
siftDown(arr, maxIndex, length);
}
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
private void quickSort(int[] arr, int begin, int end) {
if (begin >= end) {
return;
}
int left = begin;
int right = end;
int cur = arr[left];
while (left < right) {
while (left < right && arr[right] >= cur) {
right --;
}
if (left < right) {
swap(arr, left, right);
}
while (left < right && arr[left] <= cur) {
left ++;
}
if (left < right) {
swap(arr, left, right);
}
}
quickSort(arr, begin, left - 1);
quickSort(arr, left + 1, end);
}
}