【剑指Offer面试题】 九度OJ1371:最小的K个数

题目链接地址:
http://ac.jobdu.com/problem.php?pid=1371

题目1371:最小的K个数

时间限制:1 秒内存限制:32 兆特殊判题:否提交:5938解决:1265
题目描写叙述:
输入n个整数,找出当中最小的K个数。比如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
输入:
每一个測试案例包括2行:
第一行为2个整数n。k(1<=n。k<=200000),表示数组的长度。
第二行包括n个整数。表示这n个数。数组中的数的范围是[0,1000 000 000]。


输出:
相应每一个測试案例。输出最小的k个数,并按从小到大顺序打印。


例子输入:
8 4
4 5 1 6 2 7 3 8
例子输出:
1 2 3 4


思路分析:

这题方法非常多,也是面试easy问的问题。


1. 快排后,取出前k个元素。

这种时间复杂度为O(nlogn+k),空间复杂度O(1)。


2. 用map直接统计每一个值出现的次数。

然后数出最小的k个值就可以。空间复杂度O(n)。


3. 採用小顶堆,n个元素建成一个小顶堆,将堆顶与数组的最后一个元素交换。这样最小的元素就保存在了数组的最后一个位置,k次调整后,最小的k个元素便保存在了数组的最后k个位置。时间复杂度为O(n+klogn);改变输入数组,空间复杂度为O(1),不改变输入数组空间复杂度为O(n)。
4. 用最大堆来存k个数,剩下的n-k个数每一个都和堆顶比較,比堆顶小时。就把堆顶元素替换掉。

採取先pop()后push()的方法替换。时间复杂度为O(k+(n-k)logk)。空间复杂度O(k)。(适合海量数据处理)


代码

方法四代码:
优先队列就是大顶堆。队头元素最大。
http://www.cppblog.com/darren/archive/2009/06/09/87224.html

/********************************* 
【剑指Offer面试题】 九度OJ1371:最小的K个数
Author:牧之丶  Date:2015年
Email:bzhou84@163.com 
**********************************/
#include <stdio.h>
#include <stdlib.h>  
#include <string>
#include <cstring>
#include <math.h>
#include <stack>
#include <vector>
#include <queue>  
#include <iostream>
#include<algorithm>
#include <map>
#include <queue>
using namespace std;

int main()
{
    // 大顶堆
    priority_queue<int, vector<int>, less<int> > pQueue;
    vector<int> result;
    int n, k;
    int i, tmp;

    while(scanf("%d%d", &n, &k)!=EOF){
        while(!pQueue.empty()){
            pQueue.pop();
        }
        result.clear();

        if(k > n){
            k = n;
        }
        for(i = 0; i < k; ++i){
            scanf("%d", &tmp);
            pQueue.push(tmp);
        }

        for(i = k; i < n; ++i){
            scanf("%d", &tmp);
            if(tmp < pQueue.top()){
                pQueue.pop();
                pQueue.push(tmp);
            }
        }

        while(!pQueue.empty()){
            result.push_back(pQueue.top());
            pQueue.pop();
        }

        for(i = (int)result.size() - 1; i >= 0; --i){
            if(i == (int)result.size() - 1){
                printf("%d", result[i]);
            }else{
                printf(" %d", result[i]);
            }
        }
        printf("\n");
        result.clear();
    }

    return 0;
}
/**************************************************************
    Problem: 1371
    Language: C++
    Result: Accepted
    Time:980 ms
    Memory:2292 kb
****************************************************************/
posted @ 2017-06-14 18:12  claireyuancy  阅读(176)  评论(0编辑  收藏  举报