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

 

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

分析:

方法(1):排序(升序),找前k个数据

vector GetLeastNumbers_Solution(vector input, int k) {
        //在n个数中找最小的前k个数(排序)
        
        vector v;
        if(k<=0 || input.size()<=0 || k>input.size())
            return v;
        
        sort(input.begin(), input.end());//默认是升序
        int i=0;
        while(i

方法(2):用n个数据的前建k个元素的大堆,然后用剩下的元素与堆顶元素比较,比堆顶小的元素入堆,直到完,最后堆中保留的就是最小的前k个元素

//向下调整算法(建大堆)
        void Adjustdown(vector& a, int n, int parent)
        {
            int child=parent*2+1;//左孩子
            while(childa[child])//保证a[child]是最大孩子
                {
                    child++;
                }
                
                if(a[parent] GetLeastNumbers_Solution(vector input, int k) {
        //在n个数中找最小的前k个数(堆)
        
        vector v;
        if(k<=0 || input.size()<=0 || k>input.size())
            return v;
        
        //先拿前k个数建一个大堆
        
        //从最后一个节点的父亲开始调整
        for(int i=(k-2)/2;i>=0;i--)
        {
            Adjustdown(input,k,i);
        }
        
        //将剩下的数据与堆顶数据比较,小于堆顶元素就入堆(替换堆顶,并且将堆顶向下调整)
        for(int i=k;i

方法(3):使用优先级队列(要显式传greater仿函数,因为这才是升序,默认是降序的),将原来vector的数据依次push到这个优先级队列中,可以使得最后的元素按照升序排序,然后将前k个push到返回的vector中

vector GetLeastNumbers_Solution(vector input, int k) {
        //在n个数中找最小的前k个数(排序)
        
        vector v;
        if(k<=0 || input.size()<=0 || k>input.size())
            return v;
        
        priority_queue, greater> q;//小堆
        
        for(int i=0;i

方法(4):利用快排思想,找到一个基准值,使得它大于左边所有数,小于右边所有数,如果这个基准值的下标是k-1的话就说明找到了,否则反复找,直到知道为止

int partion(vector& v, int begin, int end)
    {
        int key=v[begin];//保存v[begin]到变量key里
        
        while(begin=key)
            {
                end--;
            }
            //来到这,说明v[end]key了
            v[end]=v[begin];
        }
        //来到这v[begin]的是 GetLeastNumbers_Solution(vector input, int k) {
        //在n个数中找最小的前k个数(堆)
        
        vector v;
        if(k<=0 || input.size()<=0 || k>input.size())
            return v;
        
        //调用partion函数看返回的pos是不是k-1(最小的前k个数据,下标是0,1...k-1)
        int pos=partion(input, 0, input.size()-1);
        
       while(pos!=k-1)
        {
            if(pos>k-1)//说明在左半面
            {
                pos=partion(input, 0, pos-1);
            }
            else
            {
                pos=partion(input, pos+1, input.size()-1);
            }
        }
        //来到这说明pos==k-1了
        
        vector v1(input.begin(), input.begin()+k);
        return v1;
    }

 

你可能感兴趣的:(剑指offer)