题解 | #排序#
最小的K个数
http://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf
//手写的堆排序
//1、构建小跟堆
//2、交换之后 再从根节点开始调整
void adjust_heap(vector<int> &input, int i, int size) {
int tp = input[i]; //tp保存根节点的值
int k;
//假设i是从根节点0开始调整,当根节点的左右字树调整完之后,再应该调整k=3索引开始调整,这时的父节点应该是1索引的位置
for(k = 2 * i+1; k < size; k = 2 * k + 1) {
if(k + 1 < size && input[k+1] < input[k]) {
k++; //k指向子树中最小的节点位置
}
if(input[k] < tp) { //如果根节点大于左右子树
input[i] = input[k]; //把子节点覆盖根节点
i = k; //i指向上面tp根节点需要交换的位置
} else { //表示i节点位置是符合小跟堆的 直接跳出循环 后面看其它位置符不符合
break;
}
}
input[i] = tp; //将其根节点插入到合适的位置
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
//先将数组中的所有元素调整为小跟堆
for(int i = input.size()/2-1; i >= 0; i--) {
adjust_heap(input, i, input.size());
}
for(int i = input.size()-1; i >= 0 && k > 0; k--, i--) {
swap(input[0], input[i]); //交换头尾节点 继续调整根节点为小根堆
res.push_back(input[i]);
adjust_heap(input, 0, i);
}
cout<<res.size()<<endl;
return res;
}
//使用容器中的优先队列 底层也是堆排序
vector<int> GetLeastNumbers_Solution1(vector<int> input, int k) {
priority_queue<int, vector<int>, greater<int>> prior; //默认是大跟堆,需要调整为小跟堆
vector<int> res;
if(input.size() <= 0)
return res;
for(int item : input) {
prior.push(item);
}
while(k > 0) {
res.push_back(prior.top());
prior.pop();
k--;
}
return res;
}
查看10道真题和解析