剑指offer-30最小k个数

来源:互联网 发布:淘宝出售假货怎么处罚 编辑:程序博客网 时间:2024/05/16 06:16

题目:输入n个数,找出其中的最小的k个数。

根据不同的方法,其中可以直接对输入的数组排序,时间复杂度是O(nlogn),如下所示:

class Solution {public:    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {        vector<int> small;        if(k>input.size())            return small;        if(k==input.size())            return input;                sort(input.begin(),input.end());        int i=0;           for(vector<int>::iterator iter=input.begin();iter!=input.end();iter++)           {               if(i<k)               {            small.push_back(*iter);                   i++;               }               else                    break;           }        return small;    }};

也可以对数组进行K次的冒泡排序,其时间复杂度是O(kn),代码如下:

class Solution {public:    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {        vector<int> result ;        if(k > input.size()) return result;        for(int l= input.size()-1;l>input.size()-1-k;--l)        {            int m=l;            while(m>0)            {                if(input[m-1]>input[m])                    swap(input[m-1],input[m]);                --m;            }        }        for(int i=0; i<k ; ++i)            result.push_back(input[i]);        return result;    }    };
对数组利用快排的partition函数进行排序,使得最小的k个数在数组的前面(这最小k个数不一定是有序的),可以达到时间复杂度O(n)的算法。代码如下所示:

class Solution {public:    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {        vector<int> small;        int size=input.size();        if(k>size)            return small;        if(k==size)            return input;        int start = 0;        int end = size-1;        int index = Partition(input, start, end);        while(index != k)        {            if(index > k)            {                end = index-1;                index = Partition(input, start, end);            }            else            {                start = index+1;                index = Partition(input, start, end);            }        }        for(int i = 0; i<k; ++i)        {            small.push_back(input[i]);        }        return small;    }    int Partition(vector<int> &input, int start, int end)    {        int index = (start + end )/2;        swap(input[index], input[end]);        int small = start-1;        for(index = start; index < end; ++index)        {            if(input[index]<input[end])            {                ++small;                if(small != index)                    swap(input[index], input[small]);            }        }        ++small;        swap(input[small], input[end]);                return small;    }};
若要求在不能更改数组的数据情况下,可以使用堆排序,其时间复杂度为O(nlogk)

class Solution {public:    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {        vector<int> small;        if(k>input.size())            return small;        if(k==input.size())            return input;
//调整前k个数为最大堆        for(int i=(k-1)/2; i>=0; --i)            adjust(input, i, k-1);
//从第k+1个元素起与最大堆的堆顶比较,若大于堆顶元素,则该元素不在最小k个数中,否则与堆顶元素交换并调整为最大堆        for(int j=k; j<input.size(); ++j)        {            if(input[j]<input[0])            {                swap(input[j],input[0]);                adjust(input, 0, k-1);            }        }        for(int i = 0; i<k; ++i)        {            small.push_back(input[i]);        }        return small;    }    void adjust(vector<int> &input, int i, int n)    {        int j;        int tmp = input[i];        j = 2*i+1;        while(j<=n)        {            if(j<n && input[j]<input[j+1])                ++j;            if(tmp>=input[j])                break;            input[(j-1)/2] = input[j];            j = 2*j+1;        }        input[(j-1)/2] = tmp;    }};






0 0
原创粉丝点击