题目14:最小的K个数

http://ac.jobdu.com/problem.php?cid=1039&pid=13

题目描述:

输入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
这道题目可能是有史以来做得最恶心的题目了!题目的意思很简单,就是输出n个数中最小的k个数!
1。开始做,就想着排序,再直接输出k个数,但是,这显然会超时,时间复杂度是O(n*logn);
2。第二种思路是取前k个数,再从后面n - k个元素中找出比前k个元素最大值还小的元素进行交换,时间复杂度是O((n-k)*k)!,不过,数据不弱,还是照样超时!
3。于是尝试第三种思路,利用堆排序的思想,构造前k个元素的大根堆,再在后面的元素中找比堆顶小的元素与堆顶进行交换,第次交换后,对堆顶进行重建堆!这样时间复杂度O(n + k*logk),还是照样超时!
4。第四种思路是找到所有元素中第k大的元素,再扫描一遍,求出比k小的元素,再进行排序,这样时间复杂度同样O(n + k*logk)! 不过
居然可以AC!

以下是AC代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <set>
#include <vector>
using namespace std; 


vector<int> myvector;
vector<int>::iterator it;

int main ()
{
    
    int i , n , k, p;
    while(scanf("%d %d",&n,&k) == 2)
    {
                    myvector.clear();
                    for(i = 0;i < n;i++)
                    {
                          scanf("%d",&p);
                          myvector.push_back(p);
                    }
                    //random_shuffle (myvector.begin(), myvector.end());//加上这句超时,去掉就可以AC 
                    nth_element (myvector.begin(), myvector.begin()+k, myvector.end());
                    sort(myvector.begin(), myvector.begin()+k);
                    for (it = myvector.begin() ; it < myvector.begin() + k - 1; ++it)
                          printf("%d ",*it);
                      printf("%d\n",*it);
                          
                    
    } 
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值