至此,我终于明白了哈希表真正的妙用。
目录
文章目录
前言
一、珠玑妙算
二、具体实现
1.哈希表的构建
2.总结规律
1)给出两个字符串:"YBBY","GYYB",构建哈希表:(少猜了一个B)
2)给出两个字符串:"RGBY","GGRR",构建哈希表:(多猜的一个R是无效的)
3)给出两个字符串:"GGBB","RBYB",构建哈希表:(有真猜中的,需要在猜中的总数中减去真猜中的个数)
总结
前言
这道题需要使用哈希表,如果只是硬解,会有很多情况考虑不周。
一、珠玑妙算
珠玑妙算游戏(the game of master mind)的玩法如下。
计算机有4个槽,每个槽放一个球,颜色可能是红色(R)、黄色(Y)、绿色(G)或蓝色(B)。例如,计算机可能有RGGB 4种(槽1为红色,槽2、3为绿色,槽4为蓝色)。作为用户,你试图猜出颜色组合。打个比方,你可能会猜YRGB。要是猜对某个槽的颜色,则算一次“猜中”;要是只猜对颜色但槽位猜错了,则算一次“伪猜中”。注意,“猜中”不能算入“伪猜中”。
给定一种颜色组合
solution
和一个猜测guess
,编写一个方法,返回猜中和伪猜中的次数answer
,其中answer[0]
为猜中的次数,answer[1]
为伪猜中的次数。示例:
输入: solution="RGBY",guess="GGRR" 输出: [1,1] 解释: 猜中1次,伪猜中1次。提示:
len(solution) = len(guess) = 4
solution
和guess
仅包含"R"
,"G"
,"B"
,"Y"
这4种字符
二、具体实现
1.哈希表的构建
直接将四个字母的ASCII码进行和10取余是较好构建表的办法。
于是,可得:
R——2,G——1,B——6,Y——9。
所以只需要构建一个10个元素大小的int数组。
2.总结规律
1)给出两个字符串:"YBBY","GYYB",构建哈希表:(少猜了一个B)
2)给出两个字符串:"RGBY","GGRR",构建哈希表:(多猜的一个R是无效的)
3)给出两个字符串:"GGBB","RBYB",构建哈希表:(有真猜中的,需要在猜中的总数中减去真猜中的个数)
可得规律:
真猜中数:用一个变量遍历两个字符串(solution,guess),对应位置相等即加到realCount中得到真猜中数。
伪猜中数:用一个变量去同时遍历两个哈希表,如果不为0,那么说明这个字母被猜中(不管真假),此时需要取两表中较小值(如果realHash中的小,那么说明猜的次数比真正有的次数多,多猜的是无效的;反之,如果fakeHash中的小,那么说明猜的次数比真正有的次数少,以猜中的为准),相加为猜中个数,将这个数与真猜中个数相减得到伪猜中数。
代码如下(示例):
int* masterMind(char* solution, char* guess, int* returnSize) {
int realHash[10] = { 0 };
int fakeHash[10] = { 0 };
int realCount = 0;
int fakeCount = 0;
for (int i = 0; i < 4; i++)
{
if (solution[i] == guess[i])
{
realCount++;
}
// 猜中的哈希表
realHash[solution[i] % 10]++;
}
for (int i = 0; i < 4; i++)
{
// 伪猜中的哈希表
fakeHash[guess[i] % 10]++;
}
for (int i = 0; i < 10; i++)
{
if (fakeHash[i] != 0 && realHash[i] != 0)
{
if (fakeHash[i] < realHash[i])
{
fakeCount += fakeHash[i];
}
else
{
fakeCount += realHash[i];
}
}
}
*returnSize = 2;
int* ans = (int*)malloc(sizeof(int) * 2);
ans[0] = realCount;
ans[1] = fakeCount - realCount;
return ans;
}
总结
哈希表真的很妙!