輸入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<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //在n個數中找最小的前k個數(排序)
        
        vector<int> v;
        if(k<=0 || input.size()<=0 || k>input.size())
            return v;
        
        sort(input.begin(), input.end());//默認是升序
        int i=0;
        while(i<k)
        {
            v.push_back(input[i]);
            i++;
        }
        return v;
    }

方法(2):用n個數據的前建k個元素的大堆,然後用剩下的元素與堆頂元素比較,比堆頂小的元素入堆,直到完,最後堆中保留的就是最小的前k個元素

//向下調整算法(建大堆)
        void Adjustdown(vector<int>& a, int n, int parent)
        {
            int child=parent*2+1;//左孩子
            while(child<n)
            {
                if(child+1<a.size() && a[child+1]>a[child])//保證a[child]是最大孩子
                {
                    child++;
                }
                
                if(a[parent]<a[child])
                {
                    swap(a[parent], a[child]);
                    
                    parent=child;
                    child=parent*2+1;
                }
                else
                {
                    break;
                }
            }
        }
    
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //在n個數中找最小的前k個數(堆)
        
        vector<int> 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<input.size();i++)
        {
            if(input[i]<input[0])
            {
                input[0]=input[i];
                Adjustdown(input,k, 0);
            }
        }
        
        //小堆中數據尾插到返回的vector中
        for(int i=0;i<k;i++)
        {
            v.push_back(input[i]);
        }
     
       return v;
    }

方法(3):使用優先級隊列(要顯式傳greater仿函數,因爲這纔是升序,默認是降序的),將原來vector的數據依次push到這個優先級隊列中,可以使得最後的元素按照升序排序,然後將前k個push到返回的vector中

vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        //在n個數中找最小的前k個數(排序)
        
        vector<int> v;
        if(k<=0 || input.size()<=0 || k>input.size())
            return v;
        
        priority_queue<int, vector<int>, greater<int>> q;//小堆
        
        for(int i=0;i<input.size();i++)//建立優先級隊列(升序排序)
        {
            q.push(input[i]);
        }
        
        while(k)
        {
            v.push_back(q.top());
            q.pop();
            k--;
        }
        
        return v;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章