面试小记-1-不重复输出[1-10000]区间数字

今天去面了一家不大不小的公司,面试题应该说不算难,唯一一道编程题是要求随机输出[1-10000]中的数字,不能重复,要考虑效率。

一看要求不能重复脑门一下闪到哈希表,于是啪啦啪啦写道建立一个10001大小的int数组做哈希表用值做下标用rand函数什么的,恩没错写的是文字不是代码。。。脑袋抽了。。。交卷后等了几分钟前台MM走过来很礼貌的说“对不起先生您的成绩离我们的要求有点大不好意思”,“有点大”这三个字如果是MM在其他场合对我说我会很高兴,但这让我有点不爽。

回来上网搜了下相关题目资料总结下,觉得虽然题目难度不大,但要答全有难度;另一个编程题我竟然用文字叙述,伪码都不是,可能也是一个重要原因,而且可能算法也不是甲方想要的;最后一题竟然是数据库,不算难的一题但自己实在很久不弄数据库了只能凭大学映象瞎编,至少对了一半。

发完牢骚开始正题。该题自己写的时候也发现如果n很大的话在随机最后几个数的时候效率会很低,但当时确实也没想到优化的方法。现在查了下有个算法是设定一个左右区间,每次将有效区间最后一个有效数字赋值到被rand的数,然后有效区间-1,相当于去除了被rand的数,于是此算法循环n次肯定完事,要是哈希表的话肯定会多循环m次。

将两种代码贴上来:

哈希:

void oneTo1W(int nummm[], int n) {
    int num[n];
    for (int i = 0; i < n + 1; i++)
        num[i] = i;
    int hashtable[n + 1];
    memset(hashtable, 0, sizeof(int) * (n + 1));
    int count = 0;
    int random = 0;
    srand((unsigned)time(NULL));

    while (count < n) {
        random = rand() % n + 1;
        if (hashtable[random] == 0) {
            hashtable[random] = random;
            count++;
            printf("%d ", random);
        }
    }
    printf("\n%d\n", count);
}

左右区间替代法:

void fix_oneTo1W(int n) {
    int table[n];
    for (int i = 0; i < n + 1; i++)
        table[i] = i;
    int end = n;
    srand((unsigned)time(NULL));
    int ran = 0;
    int count = 0;
    while (end > 0) {
        ran = rand() % end + 1;
//        printf("ran-->%d, table[ran]-->%d-->", ran, table[ran]);
        printf("%d ", table[ran]);
        table[ran] = table[end];
        end--;
        count++;
    }
    printf("count-->%d\n", count);
}

最后,两种方法我都跑了一下,n等于1w、10w时时间都差不多,哈希表也没见得慢多少,100w时两种都要长时间运行(也可能我写得不对),也就是说算法这东西确实有优劣之分,但有时候实际效果却不见得有鸿沟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值