Codeup[100000582]Be Unique

本文探讨了在大量参与者下通过哈希表和数组优化下注计数问题的两种解决方案,第一种方法的时间复杂度为O(n),而第二种改进方案实现了O(1)效率,速度提升明显。

题目如下:
在这里插入图片描述不要看是英文的题目,但是内容非常简单。就是一群人下赌注,第1个压得赌注是唯一的人获胜。
由于参与的人可能比较多,多至10510^{5}105,因此可以使用哈希表的方式来快速解决。
下面是第1种解决方案,通过定义1个结构体,其中成员d存储对应的赌注,而c存储对应出现的次数。
读取的过程中,查找对应赌注的位置,然后将其出现次数加1。
下面对应的实现代码:

#include <stdio.h>

typedef struct {
    int d[100001];
    int c[100001];
    int length;
} Relation;

int main(int argc, char **argv) {
    int n;
    while (scanf("%d", &n) != EOF) {
        int m;
        Relation r = {0};
        // 耗费时间的搜索
        for (int i = 0; i < n; ++i) {
            scanf("%d", &m);
            int index = -1;
            for (int j = 0; j < r.length; ++j) {
                if (r.d[j] == m) {
                    index = j;
                    r.c[j]++;
                    break;
                }
            }
            if (index == -1) {
                int len = r.length;
                r.d[len] = m;
                r.c[len] = 1;
                r.length++;
            }
        }
        int finish = -1;
        for (int k = 0; k < r.length; ++k) {
            if (r.c[k] == 1) {
                // 找到对应的索引
                finish = k;
                break;
            }
        }
        if (finish != -1) {
            printf("%d\n", r.d[finish]);
        } else {
            printf("%s\n", "None");
        }
    }
    return 0;
}

这个代码有一个非常不好的地方在于,找到对应的赌注是非常耗时的,时间复杂度为O(n)。因此,它不是1个很好的解决方案。
下面看另外1种更为恰当的解决方案,通过定义2个数组。当读取时依次将赌注写入到数组中。之后通过哈希表映射到对应的元素上,比如第1个赌注为30,那么将第30个元素的次数设置为1。而这样的方式,时间复杂度为O(1)。
下面是对应实现的代码:

#include <stdio.h>

int d[100001];
int hash[100001];

int main(int argc, char **argv) {
    int n;
    while (scanf("%d", &n) != EOF) {
        for (int i = 0; i < n; ++i) {
            scanf("%d", &d[i]);
            hash[d[i]]++;
        }
        int finish = -1;
        for (int k = 0; k < n; ++k) {
            if (hash[d[k]] == 1) {
                finish = d[k];
                break;
            }
        }
        if (finish != -1) {
            printf("%d\n", finish);
        } else {
            printf("%s\n", "None");
        }
    }
    return 0;
}

最后是测试通过后的结果,可以发现第1种方法运行时间为286ms,而第2种方式的运行时间为17ms,整整快了近17倍。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值