求最小的K个数

方法一:利用快排的思想,复杂度为O(n)???

class Solution {
public:
    int Partition(vector<int>& input, int begin, int end)
{
    int low = begin;
    int high = end;

    int pivot = input[low];
    while (low<high)
    {
        while (low<high&&pivot <= input[high])
            high--;
        //input[low] = input[high];
        swap(input[low], input[high]);
        while (low<high&&pivot >= input[low])
            low++;
        //input[high] = input[low];
        swap(input[low], input[high]);
    }
    input[low] = pivot;
    return low;
}

vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {

    int len = input.size();
    if (len == 0 || k>len||k<=0) return vector<int>();
    if (len == k) return input;

    int start = 0;
    int end = len - 1;
    int index = Partition(input, start, end);
    while (index != (k - 1))
    {
        if (index>k - 1)
        {
            end = index - 1;
            index = Partition(input, start, end);
        }
        else
        {
            start = index + 1;
            index = Partition(input, start, end);
        }
    }

    vector<int> res(input.begin(), input.begin() + k);

    return res;
    }
};

 方法二:利用堆排序的思想,时间复杂度为O(nlogk)

利用堆排序,特别适用于海量数据中寻找最大或者最小的k个数字。即构建一个大堆容器,初始化大小为k,变量初始数,如初始数组大小小于等于k直接返回,如果大于k,则选择数组的前k个元素,填充堆,然后调整为最大堆。调整完之后,继续从初始数组中拿出一个元素,如果该元素比大堆的堆顶小,则替换堆顶,继续调整为最大堆,如果大于等于堆顶则直接丢弃,不作调整。 
PS:大堆还是小堆的选择很重要,不是寻找最小的k个元素就要选择小堆,而且恰恰相反。寻找最小的k个数,其实就是寻找第k个大的元素,即寻找k个数中最大的,不断调整堆,堆得元素个数是k,堆顶是最大值,遍历完初始数组后,堆中存在的元素即使我们所要寻找的k个最小元素。

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {if(k<=0||k>input.size()||input.size()==0)return vector<int>();
        vector<int>max_heap(k,0);
        for(int i=0;i<k;i++){
            max_heap[i]=input[i];
        }
        for(int i=(k-1)/2;i>=0;i--)
            maxheap_down(max_heap,i,k-1);
        for(int i=k;i<input.size();i++){
            if(input[i]<max_heap[0]){
                max_heap[0]=input[i];
                maxheap_down(max_heap,0,k-1);
            }
        }
        return max_heap;
    }
    
    void maxheap_down(vector<int>&a,int start,int end){
        int c=start;
        int value=a[c];
        int l=2*c+1;
        for(;l<=end;c=l,l=2*c+1){
            if(l<end&&a[l]<a[l+1])l++;
            if(value>a[l])break;
            else{
                a[c]=a[l];
                a[l]=value;
            }
        }
    }
};

 

posted @ 2018-05-20 10:36  追逐更好的自己  阅读(640)  评论(0编辑  收藏  举报