题目如下:
不要看是英文的题目,但是内容非常简单。就是一群人下赌注,第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倍。

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

被折叠的 条评论
为什么被折叠?



