BullsAndCows
Problem
你正在和你的朋友玩 猜数字(Bulls and Cows)游戏:你写下一个数字让你的朋友猜。每次他猜测后,你给他一个提示,告诉他有多少位数字和确切位置都猜对了(称为“Bulls”, 公牛),有多少位数字猜对了但是位置不对(称为“Cows”, 奶牛)。你的朋友将会根据提示继续猜,直到猜出秘密数字。
请写出一个根据秘密数字和朋友的猜测数返回提示的函数,用 A 表示公牛,用 B 表示奶牛。
请注意秘密数字和朋友的猜测数都可能含有重复数字。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bulls-and-cows
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Example 1
输入: secret = "1807", guess = "7810"
输出: "1A3B"
解释: 1 公牛和 3 奶牛。公牛是 8,奶牛是 0, 1 和 7。
Example 2
输入: secret = "1123", guess = "0111"
输出: "1A1B"
解释: 朋友猜测数中的第一个 1 是公牛,第二个或第三个 1 可被视为奶牛。
说明: 你可以假设秘密数字和朋友的猜测数都只包含数字,并且它们的长度永远相等。
Solution-1 直接按照描述求解
这种做法同样可以适用于两个string长度不同len(guess) > len(secret)
的情况
class Solution {
public:
string getHint(string secret, string guess) {
int bulls{0}, cows{0};
map<char, int> chars;
for (char c : secret) {
if (chars.find(c) == chars.end()) chars[c] = 1;
else chars[c] += 1;
}
for (size_t i = 0; i < secret.size(); ++i) {
if (guess[i] == secret[i] && chars[guess[i]] > 0) {
chars[guess[i]] -= 1;
bulls += 1;
guess[i] = 'e';
}
}
for (size_t i = 0; i < guess.size(); ++i) {
if (chars.find(guess[i]) != chars.end() && chars[guess[i]] > 0) {
chars[guess[i]] -= 1;
cows += 1;
}
}
ostringstream strio;
strio << bulls << "A" << cows << "B";
return strio.str();
}
};
Solution-2 优化的方法
这种方法只适用于两个字符串长度一样的情况:len(secret) == len(guess) == len
,因为字符只有0-9十个,所以可以直接使用数组记录,bulls
同样可以直接统计。而对于cows
,我们只考虑没有归入bulls
中的元素,在bucks
中记录的元素是num_elem_in_secret - num_elem_in_guess
, 我们应该有关系:sum(bucks) == 0
,或者假设bucks
是两个向量x
和y
之差,其中x[i]=#i in secret
, y[i]=#i in guess
. 那么应该有sum(x)=sum(y)=len-bulls
,那么在这两个向量相减的过程中,相互抵消掉的部分就是同时存在于secret
和guess
的部分,多出来的正值的部分就是只存在于secret
中的部分,多出来的负值的部分就是只存在于guess
中的部分,那么我们只需要使用len-bulls-sum([i for i in bucks if i > 0])
就是同时存在于guess
和cows
中并且不在bulls
中的元素个数,即cows
.
// Version 1
class Solution {
public:
string getHint(string secret, string guess) {
int bulls{0}, cows{0};
array<int, 10> bucks;
bucks.fill(0);
for (size_t i = 0; i < secret.size(); ++i) {
if (guess[i] == secret[i]) {
++bulls;
continue;
}
bucks[guess[i] - '0'] += 1;
bucks[secret[i] - '0'] -= 1;
}
for (int i : bucks) {
if (i > 0) cows += i;
}
cows = (int)guess.size() - bulls - cows;
ostringstream strio;
strio << bulls << "A" << cows << "B";
return strio.str();
}
};
// Version 2
class Solution {
public:
string getHint(string secret, string guess) {
int bulls{0}, cows{0};
array<int, 10> bucks;
bucks.fill(0);
for (size_t i = 0; i < secret.size(); ++i) {
if (guess[i] == secret[i]) {
++bulls;
continue;
}
bucks[guess[i] - '0'] += 1;
bucks[secret[i] - '0'] -= 1;
}
for (int i : bucks) {
if (i < 0) cows += i;
}
cows = (int)guess.size() - bulls + cows;
ostringstream strio;
strio << bulls << "A" << cows << "B";
return strio.str();
}
};