【剑指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;
    }
};
全部评论

相关推荐

05-24 14:12
门头沟学院 Java
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务