Question
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。
思路
使用堆排序的方法对数组进行排序后,取前k个最小值,这里手动实现建堆;
升序--使用大顶堆
降序--使用小顶堆
Code
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 > input.length || k == 0)
return res;
//建立大顶堆
for(int i = input.length; i > 0; i--)
{
BuildMaxHeap(input , i);
Swap(input, i); //将大值放到后面
}
for(int i = 0; i < k; i++)
{
res.add(input[i]);
}
return res;
}
//建立大顶堆
private void BuildMaxHeap(int[] input , int len)
{
//从最后一个非叶子结点开始建立大顶堆
for(int i = len / 2 - 1; i >= 0; i--)
{
//根结点小于左子树
if((2 * i + 1) < len && input[i] < input[2 * i + 1])
{
int tmp = input[i];
input[i] = input[2*i+1];
input[2*i+1] = tmp;
//检查交换后左子树是否满足大顶堆性质
if(2*(2*i+1)+1< len && input[2*i+1] < input[2*i+1] ||
2*(2*i+1) + 2 < len && input[2*i+1] < input[2*(2*i+1)+2])
{
BuildMaxHeap(input, len);
}
}
//根结点小于右子树
if((2*i+2) < len && input[i] < input[2*i+2])
{
int tmp = input[i];
input[i] = input[2*i+2];
input[2*i+2] = tmp;
if(2*(2*i+2) + 1 < len && input[2*i+2] < input[2*(2*i+2)+1] ||
2*(2*i+2) + 2 < len && input[2*i+2] < input[2*(2*i+2)+2])
{
BuildMaxHeap(input,len);
}
}
}
}
//将根结点与最后一个元素交换位置
private void Swap(int[] input, int len)
{
int tmp = input[0];
input[0] = input[len-1];
input[len-1] = tmp;
}
} 
京公网安备 11010502036488号