题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
题目分析
这个题主要是通过构建大根堆来实现的,首先构建大小为k的大根堆,这样数组中最大的k个数就在其中,然后和数组中的其他树进行比较:
如果数组中的数<大根堆堆顶,那么将这个数和大根堆堆顶进行交换,之后在进行大根堆顺序的调整,这样一直遍历,直到数组末尾。
最终大根堆中的k个数就是数组中最小的k个数。
详情请看代码注释。
代码
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
{
if(input.empty()||k==0||k>input.size())
return vector<int>{};
vector<int> result;
for(int i=input.size()/2-1;i>=0;i--)
adjustHeap(input,i,k);//构建大根堆
//将第k+1个数到末尾和大根堆的k个数进行比较
for(int i=k;i<input.size();i++)
{
if(input[0]>input[i])
{
int temp=input[i];
input[i]=input[0];
input[0]=temp;
adjustHeap(input,0,k);//重新调整堆
}
}
//构建最终的k个数
for(int i=0;i<k;i++)
{
result.push_back(input[i]);
}
return result;
}
void adjustHeap(vector<int>&input,int i,int n)
{
int left=2*i+1;//i结点的左孩子
int right=2*i+2;//i结点的右孩子
int largest=i;//父结点,左孩子,右孩子中最大值的下标
if(left<n&&input[left]>input[largest])
largest=left;
if(right<n&&input[right]>input[largest])
largest=right;
if(largest!=i)
{
int tem;
tem=input[i];
input[i]=input[largest];
input[largest]=tem;
adjustHeap(input,largest,n);//递归调用,调整最大堆
}
}
};