码迷,mamicode.com
首页 > 其他好文 > 详细

【剑指offer】40、最小的K个数

时间:2018-07-21 12:15:50      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:元素   partition   amp   改变   海量   思路   ast   else   最小的k个数   

题目

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

思路一

基于partition,当 index正好为k的时候,就是第k大的数。时间复杂度O(n)

缺点:需要改变数组

class Solution {
public:
    int Partition(vector<int>& input, int begin, int end)
    {
        int low = begin, high = end;
        int pivot = input[low];
         
        while(low < high)
        {
            while( low < high && pivot<=input[high])
            {
                high--;
            }
            input[low] = input[high];
            while(low < high && pivot >= input[low])
            {
                low++;
            }
            input[high] = input[low];
        }
        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, 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;
    }
};

 

思路二

使用最大堆,存储最小的k个数字,时间复杂度为O(nlogk)。

当插入时,若该元素比容器中最大元素小,则把该元素放入。

优点:不需要更改数组,适合海量数据

class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
    {
        vector<int> result;
        int len = input.size();
        if(input.empty() || k <= 0 || len < k)
            return result;
          
        multiset<int, greater<int>> leastNumbers; // 从大到小排序
        multiset<int, greater<int>>::iterator iterGreater; // 定义迭代器
          
        vector<int>::iterator iter = input.begin();
        for(; iter != input.end(); ++iter)
        {
            // 将前k个数直接插入进multiset中,注意是小于K
            if (leastNumbers.size() < k)
                leastNumbers.insert(*iter);
            else
            {
                // 因为设置的从大到小排序,故multiset中第一个位置的元素即为最大值
                iterGreater = leastNumbers.begin();
                  
                // 如果input中当前元素比multiset中最大元素小,则替换;即保持multiset中这k个元素是最小的。
                if(*iter < *(leastNumbers.begin()))
                {
                    // 替换掉当前最大值
                    leastNumbers.erase(iterGreater);
                    leastNumbers.insert(*iter);
                }
            }
        }
          
        for(iterGreater = leastNumbers.begin(); iterGreater!=leastNumbers.end(); ++iterGreater)
            result.push_back(*iterGreater); // 将multiset中这k个元素输出
        
        return result;
    }
};

 

【剑指offer】40、最小的K个数

标签:元素   partition   amp   改变   海量   思路   ast   else   最小的k个数   

原文地址:https://www.cnblogs.com/shiganquan/p/9344759.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!