• 最小的K个数


    【问题】输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

    【思路】很多人都觉得这个问题是一个排序问题,但我觉得不一定要排序啊,可以使用堆结构(最小堆),首先将所有的元素都压入到最小堆中,每次弹出最小值就好了,一共弹出k个数。直接使用STL库中的堆结构,也就是优先级队列!代码就非常简洁了!

    class Solution {
    public:
        vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
            priority_queue<int, vector<int>, greater<int>> pq;
            vector<int> res;
            if(input.size() < k) return res;  // 返回数值内存大于输入内存,则返回空
            for(auto i: input){
                pq.push(i);
            }
            while(k--){
                res.push_back(pq.top());
                pq.pop();
            }
            return res;
        }
    };

    当然,只会用库在面试官面前是不行的,接下来我们手动使用vector实现一个最小堆!
    文章链接: 从底层实现堆结构和堆排序

    这里面我将上面文章中的最大堆改成了最小堆,右一个细节就是:heapify中有一个left+1的边界,如果不满足这个边界,那么必须返回left,而不是left+1。

    class Solution {
    public:
        void heapInsert(vector<int>& list, int index){
            while(list[index] < list[(index-1)/2]){
                swap(list[index], list[(index-1)/2]);  // 与根节点交换
                index = (index-1)/2;   // 当前位置更新
            }
        }
    
        // 改变某个值,仍然是最小堆结构
        void heapify(vector<int>& list, int index, int heapSize){
            int left = index*2+1;
            while(left < heapSize){
                int mini = (left + 1) < heapSize && list[left] > list[left+1]
                    ? left + 1 : left; 
                // 这个判断错误时只能是left,由于left+1可能出了索引范围
                mini = list[mini] < list[index] ? mini : index;
                if(mini == index){
                    break;
                }
                swap(list[mini], list[index]);
                index = mini;
                left = index*2+1;
            }
        }
    
        vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
            vector<int> res;
            if(input.size() == 0) return res;
            if(input.size() < k) return res;
            for(int i = 0;i < input.size(); i++){
                heapInsert(input, i);
            }
            int heapSize = input.size();
            while(k--){
                res.push_back(input[0]);
                swap(input[0], input[--heapSize]);
                heapify(input, 0, heapSize);
            }
            return res;
        }
    };
  • 相关阅读:
    工厂模式
    dubbo
    WebSocket WebService
    消息中间
    原型模式
    ApiPost Apifox
    Future 的使用与源码解析
    JUC 线程池的使用与源码解析
    ReentrantLock 源码解析
    CountDownLatch 的使用与源码解析
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11359217.html
Copyright © 2020-2023  润新知