[LeetCode] Bulls and Cows 公母牛游戏
You are playing the following Bulls and Cows game with your friend: You write a 4-digit secret number and ask your friend to guess it, each time your friend guesses a number, you give a hint, the hint tells your friend how many digits are in the correct positions (called "bulls") and how many digits are in the wrong positions (called "cows"), your friend will use those hints to find out the secret number.
For example:
Secret number: 1807 Friend's guess: 7810
Hint: 1
bull and 3
cows. (The bull is 8
, the cows are 0
, 1
and 7
.)
According to Wikipedia: "Bulls and Cows (also known as Cows and Bulls or Pigs and Bulls or Bulls and Cleots) is an old code-breaking mind or paper and pencil game for two or more players, predating the similar commercially marketed board game Mastermind. The numerical version of the game is usually played with 4 digits, but can also be played with 3 or any other number of digits."
Write a function to return a hint according to the secret number and friend's guess, use A
to indicate the bulls and B
to indicate the cows, in the above example, your function should return 1A3B
.
You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.
Credits:
Special thanks to @jeantimex for adding this problem and creating all test cases.
Subscribe to see which companies asked this question
class Solution { public: string getHint(string secret, string guess) { int m[256] = {0}, bulls = 0, cows = 0; for (int i = 0; i < secret.size(); ++i) { if (secret[i] == guess[i]) ++bulls; else ++m[secret[i]]; } for (int i = 0; i < secret.size(); ++i) { if (secret[i] != guess[i] && m[guess[i]]) { ++cows; --m[guess[i]]; } } return to_string(bulls) + "A" + to_string(cows) + "B"; } };
我们其实可以用一次循环就搞定的,在处理不是bulls的位置时,我们看如果secret当前位置数字的映射值小于0,则表示其在guess中出现过,cows自增1,然后映射值加1,如果guess当前位置的数字的映射值大于0,则表示其在secret中出现过,cows自增1,然后映射值减1,参见代码如下:
解法二:
class Solution { public: string getHint(string secret, string guess) { int m[256] = {0}, bulls = 0, cows = 0; for (int i = 0; i < secret.size(); ++i) { if (secret[i] == guess[i]) ++bulls; else { if (m[secret[i]]++ < 0) ++cows; if (m[guess[i]]-- > 0) ++ cows; } } return to_string(bulls) + "A" + to_string(cows) + "B"; } };
最后我们还可以稍作修改写的更简洁一些,a是bulls的值,b是bulls和cows之和,参见代码如下:
解法三:
class Solution { public: string getHint(string secret, string guess) { int m[256] = {0}, a = 0, b = 0, i = 0; for (char s : secret) { char g = guess[i++]; a += s == g; b += (m[s]++ < 0) + (m[g]-- > 0); } return to_string(a) + "A" + to_string(b - a) + "B"; } };
参考资料:
https://leetcode.com/discuss/67031/one-pass-java-solution
https://leetcode.com/discuss/67125/short-c-o-n
https://leetcode.com/discuss/67012/c-one-pass-o-n-time-o-1-space