【剑指offer】最小的k个数
最小的K个数
https://www.nowcoder.com/questionTerminal/6a296eb82cf844ca8539b57c23e6e9bf?f=discussion&toCommentId=5449680
class Solution {
public:
void AdjustHeap(vector<int> &input, int i, int len){
//i是指从第i个结点开始调整,len是指调整范围0-len
int child = 2*i + 1;
int temp = input[i];
//递归调整法
if(child < len){//当孩子节点还在调整范围内才可以调整,使用下沉调整
//把大的数下沉
if(child + 1 < len && input[child + 1] > input[child]){
child = child + 1;
}
if(input[i] < input[child]){
swap(input[i], input[child]);
AdjustHeap(input, child, len);
}
}
/*
非递归的调整法
while(child < len){//当孩子节点还在调整范围内才可以调整,使用下沉调整
//把大的数下沉
if(child + 1 < len && input[child + 1] > input[child]){
child = child + 1;
}
if(temp >= input[child])
break;
input[i] = input[child];
i = child;
child = 2*i + 1;
}
input[i] = temp;
*/
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
//用sort快排再选数太普通,再复习一遍堆排序,时间复杂度nlogn
vector<int> res;
if(input.empty() || k > input.size() || k == 0) return res;
//建堆
//算法的思想为维持一个大小为k的最大堆,再对k以后的元素进行遍历,如果有元素比堆顶的元素小的,则交换
//并且继续调整维持最大堆,这样当遍历完所有元素之后,最大堆里的k个数就是原数组最小的k个数
//该算法利用最大堆只是为了方便获取最大堆里的最大的元素,并不完全利用堆排序,另一种解法也可以利用堆排序排序完以后再取前k个数
for(int i = (k - 1)/2; i >= 0; i--){
AdjustHeap(input, i, k);
}
int i = k;
while(i < input.size()){
if(input[0] > input[i]){
swap(input[0], input[i]);
AdjustHeap(input, 0, k);
}
i++;
}
for(int i = 0; i < k; i++){
res.push_back(input[i]);
}
return res;
}
};
查看16道真题和解析