299.Bulls and Cows
给定两个等长的字符串,求这两个字符串中相同位置字符相等的个数bull,和不同位置但字符相同的个数cows,最后结合为 bull+A+cows+B.
Input: secret = "1807", guess = "7810"
Output: "1A3B"
Explanation: 1 bull and 3 cows. The bull is 8, the cows are 0, 1 and 7.
思路:
一、遍历字符串secret,将其与guess中相同位置比较,要是相等,则 bull +1,要是不等,判断这个字符是否已经在哈希字典中,若存在,则其字典中的值加1,否则,将secret的对应字符加入哈希字典中,同时记录下guess中不相等的字符组成新的字符串。最后对新的guess字符串遍历,要是字符存在字典中,则cows +1,同时将字典中的值 -1.
string getHint(string secret, string guess) { unordered_map<char, int> map; int bull = 0, cows = 0; string newGuessWord = ""; for (int i = 0; i < (int)secret.length(); i++) { if (secret[i] == guess[i]) bull += 1; else if(map.count(secret[i])) { map[secret[i]] += 1; newGuessWord += guess[i]; } else { map[secret[i]] = 1; newGuessWord += guess[i]; } } for (int i = 0; i < (int)newGuessWord.length(); i++) { if (map.count(newGuessWord[i]) && map[newGuessWord[i]] >0) { cows += 1; map[newGuessWord[i]] -= 1; } } return to_string(bull) + "A" + to_string(cows) + "B"; }
二、看了大神 Grandyang的答案。
当对应位置不相等时,直接用int a[10] = {0}; 这样的数组存储0 ~ 9这10个数字在secret出现的次数,然后再对guess中的数字遍历,当不相等时,且这个数字在数组中大于0,cows+1.利用数组,省了哈希字典。
string getHint(string secret, string guess) { int bull = 0, cows = 0; int a[10] = { 0 }; for (int i = 0; i < secret.size(); i++) { if (secret[i] == guess[i]) bull += 1; else a[secret[i] - '0'] += 1; } for (int i = 0; i < guess.size(); i++) { if (secret[i] != guess[i] && a[guess[i] - '0']) { cows += 1; a[guess[i] - '0'] -= 1; } } return to_string(bull) + "A" + to_string(cows) + "B"; }
三、同样是上面大神的思想。
string getHint(string secret, string guess) { int a[10] = { 0 }, bull = 0, cows = 0, i = 0; for (char c : secret) { char g = guess[i++]; bull += c == g; cows += (a[c - '0']++ < 0) + (a[g - '0']-- > 0); } return to_string(bull) + "A" + to_string(cows-bull) + "B"; }