输出前k大的数

总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB
描述
给定一个数组,统计前k大的数并且把这k个数从大到小输出。

输入
第一行包含一个整数n,表示数组的大小。n < 100000。
第二行包含n个整数,表示数组的元素,整数之间以一个空格分开。每个整数的绝对值不超过100000000。
第三行包含一个整数k。k < n。
输出
从大到小输出前k大的数,每个数一行。
样例输入
10
4 5 6 9 8 7 1 2 3 0
5
样例输出
9
8
7
6
5
**解题思路:
1.寻找m大个数,完全可以利用c++sort()函数,倒序输出即可(时间复杂度为O(nlogn))。
2.如果不用此法,利用分治法解决,利用快排的原理将整个数组分成一半的一半的一半的一半……例如,如果第一次分成两半,右边放比所选值key大的,左边放小的,如果左边的数量比m大,那说明多了,应该在右边数列里再分,直到数列数量==m。
3.这只是筛选了m个数,还需要排序,再次利用sort。本次时间复杂度就为O(n+mlogm),就少了一些,主要还是训练分治的方法。

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
void nuoDong(int a[],int s,int e,int k){
    if(s>=e)
        return ;
    int t=a[s];
    int i=s,j=e;
    while(i!=j){
        while(i<j&&t<=a[j]) j--;
        swap(a[j],a[i]);
        while(i<j&&t>=a[i]) i++;
        swap(a[j],a[i]);
    }
    int num=e-i+1;
    if(num==k) return;
    if(num>k) nuoDong(a,i+1,e,k);
    if(num<k) nuoDong(a,s,i-1,k-num);
}
int main(){
    int n;
    scanf("%d",&n);
    int a[100010];
    for(int i=0;i<n;i++) scanf("%d",&a[i]);
    int k;
    scanf("%d",&k);
    nuoDong(a,0,n-1,k);
    sort(a+n-k,a+n);
    for(int i=n-1;i>=n-k;i--){
        printf("%d\n",a[i]);
    }
    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值