题目

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

思考

  • 方法0: 直接排序然后返回前k个,最好的时间复杂度为 O(nlog(n))
  • 方法1: 快排的变种,时间复杂度 O(n),缺点:原址,需要把所有数都 load 到内存中
  • 方法2: 利用最大堆作为辅助,时间复杂度 O(n*lg(k)),适用于处理数据量很大的情况。

code


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution{
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k){
        vector<int> ans;
        if(k > input.size()){
            return ans;
        }

        // GetLeastNumbersPartition(input, 0, input.size()-1, k);
        // for(int i=0; i<k; i++)
        //  ans.push_back(input[i]);

        // return ans;

        return GetLeastNumbersHeap(input, k);
    }

    // parition, average time complexity - O(n)
    // note: k should less than then size of input
    void GetLeastNumbersPartition(vector<int> &input, int left, int right, int k){
        int pos = partition(input, left, right);
        if(pos == k-1){
            return;
        }else if (pos < k-1){
            GetLeastNumbersPartition(input, pos+1, right, k);
        }else{
            GetLeastNumbersPartition(input, left, pos-1, k);
        }
    }

    int partition(vector<int> &input, int left, int right){
        if(left > right)
            return -1;
        int pos = left-1;
        for(int i=left; i<right; i++){
            if(input[i] <= input[right]){
                swap(input[i], input[++pos]);
            }
        }

        swap(input[right], input[++pos]);
        // input[left, pos] <= input[pos]
        // input[pos+1, right] > input[pos]
        return pos;
    }

    // heap sort, time complexity - O(nlog(k))
    vector<int> GetLeastNumbersHeap(vector<int> &input, int k){

        if(k > input.size() || input.empty())
            return vector<int>();

        vector<int> ans(input.begin(), input.begin()+k); // max heap
        make_heap(ans.begin(), ans.end(), comp);

        for(int i=k; i<input.size(); i++){
            if(input[i] < ans.front()){ // the current value less than the maximun of heap
                pop_heap(ans.begin(), ans.end(), comp);
                ans.pop_back();

                ans.push_back(input[i]);
                push_heap(ans.begin(), ans.end(), comp);
            }
        }

        sort(ans.begin(), ans.end());

        return ans;
    }

    static bool comp(int a, int b){
        return a<b;
    }

};

int main()
{
    freopen("in.txt", "r", stdin);
    int k;

    cin >> k;

    vector<int> input;
    int cur;
    while(cin >> cur){
        input.push_back(cur);
    }

    vector<int> ans = Solution().GetLeastNumbers_Solution(input, k);

    for(int n : ans)
        cout << n << " ";
    cout << endl;

    fclose(stdin);
    return 0;
}

最小k个数的更多相关文章

  1. 求n个数中的最大或最小k个数

    //求n个数中的最小k个数        public static void TestMin(int k, int n)        {            Random rd = new Ra ...

  2. nyoj 678 最小K个数之和

    最小K个数之和 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 输入n个整数,输出其中最小的K个数之和.例如输入4,5,1,1,6,2,7,3,3这9个数字,当k=4 ...

  3. 最小K个数之和

    描述 输入n个整数,输出其中最小的K个数之和.例如输入4,5,1,1,6,2,7,3,3这9个数字,当k=4,则输出最小的4个数之和为7(1,1,2,3). 输入 测试样例组数不超过10 每个测试案例 ...

  4. 算法试题 - 找出最小 k 个数

    题目 题目:输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 解析 思路1 这一题应用堆排序算法复杂度只有O(nlog k), ...

  5. 【13】堆排序 最小K个数

    题目 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 收获 优先队列实现 (n1,n2)->n2-n1是 ...

  6. 剑指Offer28 最小的K个数(Partition函数应用+大顶堆)

    包含了Partition函数的多种用法 以及大顶堆操作 /*********************************************************************** ...

  7. 找出最小的k个数

    •已知数组中的n个正数,找出其中最小的k个数. •例如(4.5.1.6.2.7.3.8),k=4,则最小的4个数是1,2,3,4 •要求: –高效: –分析时空效率 •扩展:能否设计出适合在海量数据中 ...

  8. 编程算法 - 最小的k个数 红黑树 代码(C++)

    最小的k个数 红黑树 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入n个整数, 找出当中的最小k个数. 使用红黑树(multiset) ...

  9. 笔试算法题(03):最小第K个数 & 判定BST后序序列

    出题:输入N个整数,要求输出其中最小的K个数: 分析: 快速排序和最小堆都可以解决最小(大)K个数的问题(时间复杂度为O(NlogN)):另外可以建立大小为K的最大堆,将前K个数不断插入最大堆,对于之 ...

随机推荐

  1. Python in/not in --- if not/if + for...[if]...构建List+ python的else子句

    区分几个容易出错的地方: in 成员运算符 - 如果字符串中包含给定的字符返回 True >>>"H" in a True not in 成员运算符 - 如果字符 ...

  2. linux备份文件脚本

    #!/bin/sh #Author: Opal TODAY=`date +%Y%m%d` YESTERDAY=`date -d"-1 day" +%Y%m%d` mkdir -p ...

  3. 自签名的https证书是不安全的

    一.项目内的需求 我们做的app都是企业级的应用,而企业级的应用的下载需要遵循itms协议,itms协议下需要https链接,这就需要你的服务器支持https的协议,该协议需要申请SSL证书,我们测试 ...

  4. SSM框架整合项目 :租房管理系统

    使用ssm框架整合,oracle数据库 框架: Spring SpringMVC MyBatis 导包: 1, spring 2, MyBatis 3, mybatis-spring 4, fastj ...

  5. Java集合源码分析(一)ArrayList

    前言 在前面的学习集合中只是介绍了集合的相关用法,我们想要更深入的去了解集合那就要通过我们去分析它的源码来了解它.希望对集合有一个更进一步的理解! 既然是看源码那我们要怎么看一个类的源码呢?这里我推荐 ...

  6. 使用WinDBG调试查看C#内存转储文件

    有时候我们想查看一个正在运行的程序内存中的数据,可以在任务管理器将内存状态保存为转储文件,并使用WinDBG验证,这里我们来试试: 0.安装WinDBG 1.首先写个代码用来测试 一个class pu ...

  7. [解读REST] 6.REST的应用经验以及教训

    衔接上文[解读REST] 5.Web的需求 & 推导REST,上文根据Web的需求推导出了REST架构风格,以及REST的详细描述和解释.自从1994年以来,REST架构风格被用于指导Web架 ...

  8. [ACdream]女神教你字符串——导字符串

    Problem Description 正如大家知道的,女神喜欢字符串,而在字符串中,女神最喜欢回文字符串,但是不是所有的字符串都是回文字符串,但是有一些字符串可以进行“求导”来变成回文字符串. 字符 ...

  9. 重写equals和hashCode

    equals()方法 1. 自反性:A.equals(A)要返回true. 2. 对称性:如果A.equals(B)返回true, 则B.equals(A)也要返回true. 3. 传递性:如果A.e ...

  10. json解析eval()中文乱码问题的解决

    只需要后台post请求中添加: resp.setContentType("text/html;charset=utf-8"); req.setCharacterEncoding(& ...