王道机试指南NO.5Sort&Hash应用

版权声明:本博全为博主学习日常,均为原创,请勿转载 https://blog.csdn.net/weixin_44332298/article/details/87869881

时间限制:1s 内存限制:128MB

题目描述

给n个整数,请按从大到小的顺序输出其中前m大的数。

输入

每组测试数据有两行,第一行有两个数n,m(0 < n,m < 1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。

输出

对每组测试数据按从大到小的顺序输出前m大的数。

样例输入

5 3
3 -35 92 213 -644

样例输出

213 92 3

题目分析

1、题目给出1s的运行时限,如果最坏情况下的时间复杂度在百万级以内即可。根据题目给出的数据,即便用O(nlogn)的快排,时间复杂度也到千万级了。
题目中说“n个元素各不相同”,思考运行哈希思想,利用一个数组分别统计每一种数组是否出现过,其空间复杂度依旧在题目的限定范围内。并且统计出现数字中较大的m个数字,也仅需从尾到头遍历这个数组,时间复杂度仍在百万级。
2、由于输入数据中出现了负数,所以不能直接把输入数据当作数组下标来访问数组元素,需将每一个输入的数据都加上一个固定的偏移值,使输入数据的[-500000,500000]区间映射到数组下标的[0,1000000]区间。
3、根据输出样例,还要注意输出的格式,最后一个输出数据后没有空格。

代码

#include <stdio.h>
#include <string.h>
#define OFFSET 500000 //偏移量,用于补偿实际数字与数组下标之间的偏移
int Hash[1000001]; //记录每个数字是否出现,不出现为0,出现后标为1

int main(){
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF){
        memset(Hash, 0, sizeof(Hash)); //初始化
        for(int i = 0; i < n; i++){
            int x;
            scanf("%d", &x);
            Hash[x+OFFSET] = 1;
        }
        for(int i = 500000; i >= -500000; i--){
            if(Hash[i+OFFSET] == 1){
                printf("%d", i);
                m--;
                if(m != 0){
                    printf(" ");
                }
                else{//m=0
                    printf("\n");
                    break;
                }
            }
        }
    }
    return 0;
}

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44332298/article/details/87869881