introduction
你正在和你的朋友玩 猜数字(Bulls and Cows)游戏:你写下一个数字让你的朋友猜。每次他猜测后,你给他一个提示,告诉他有多少位数字和确切位置都猜对了(称为“Bulls”, 公牛),有多少位数字猜对了但是位置不对(称为“Cows”, 奶牛)。你的朋友将会根据提示继续猜,直到猜出秘密数字。
请写出一个根据秘密数字和朋友的猜测数返回提示的函数,用 A 表示公牛,用 B 表示奶牛。
请注意秘密数字和朋友的猜测数都可能含有重复数字。
main idea
此题需要统计两类情况,一类是同一位置相等字符的个数,第二类是数字对了但是位置不对(注意:此类一定要去除掉第一类的情况,优先考虑第一类其次才是第二类)对于第一类很好进行统计,只需要比较对应位置即可,对于第二类,我们可以采用两重循环的遍历方法,不过这样效率太低,由于字符串里面只有数字,所以我们可以采用哈希表的方法来进行一个映射,我们首先把第一个字符串里面的字符与字符出现的次数放入哈希表中即map[secret[i]-'0']++;,然后再遍历另一个字符串,每遍历一个字符在哈希表中寻找如果找得到就对这个字符所对应的次数减一,然后再把统计数字加一。这样就可以统计第二类的字符了,不过这样不加任何处理就会导致上面说到的的第二类包含第一类的情况(位置相同的字符,我们第一类统计了第二类也统计了),我们可以在统计第一类的时候就将其放入哈希表中,这样可以如果是第一类的我们就不将其放入哈希表并且把这个字符换成一个非字符(作为一个标志为,这样就可以在统计第二类的情况下,知道这个字符是不是第一类已经统计了的,如果统计了我们就不管了跳过即可。)
Code
class Solution {
public:
string getHint(string secret, string guess) {
int* map= new int[10]();//建立的hash 映射
int A = 0;
int B = 0;
string res;
for(int i = 0 ;i < secret.length(); i++)
{
if(secret[i]==guess[i]){A++;guess[i] = 'A';continue;}
map[secret[i]-'0']++;//统计密码中的每个字符出现的次数
}
for(int i = 0 ;i < secret.length(); i++)
if(guess[i]=='A')continue;
else if(map[guess[i]-'0']>0){B++;map[guess[i]-'0']--;}
res.append(to_string(A)+"A"+to_string(B)+"B");
return res;
}
};
网友评论