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