Bulls and Cows
LeetCode #299 · Medium · Strings · C++ solution with worked-out approach and complexity analysis.
Approach
Two-Pass Counting Over Non-Bull Digits
A cow is a guess digit that has a *non-bull* match left over in the secret. If we count digit frequencies of the secret only at positions where it disagrees with the guess, then walking the guess a second time and consuming from that counter is exactly the right thing — bulls never enter the counter, so they can't be double-counted as cows.
Strategy
- 1Pass 1: for each index where secret[i] != guess[i], increment
- 2Pass 2: walk both strings together.
- 3Format the result as "<a>A<b>B".
Problem description(from LeetCode)
You are playing the Bulls and Cows game with your friend. You write down a secret number and ask your friend to guess what the number is. When your friend makes a guess, you provide a hint: - The number of "bulls": digits in the guess that are in the correct position. - The number of "cows": digits in the guess that exist in the secret but are in the wrong position. Specifically, non-bull digits of the guess that could be rearranged to become bulls. Return the hint formatted as "xAyB", where x is the number of bulls and y is the number of cows. Both strings may contain duplicate digits.
Examples
- Input:
- secret = "1807", guess = "7810"
- Output:
- "1A3B"
- Input:
- secret = "1123", guess = "0111"
- Output:
- "1A1B"
- Note:
- Only one of the two unmatched 1s in the guess counts as a cow, because there is only one non-bull 1 left in the secret to pair with.
Constraints
- •1 <= secret.length, guess.length <= 1000
- •secret.length == guess.length
- •secret and guess consist of digits only.
C++ Solution
class Solution {
public:
string getHint(string secret, string guess) {
int a = 0, b = 0;
vector<int> count = vector<int>(10, 0);
for (int i = 0; i < secret.size(); i++)
if (secret[i] != guess[i]) count[secret[i] - '0']++;
for (int i = 0; i < secret.size(); i++) {
int s = secret[i] - '0';
int g = guess[i] - '0';
if (s == g) a++;
else if (count[g] > 0) {
count[g]--;
b++;
}
}
return to_string(a) + 'A' + to_string(b) + 'B';
}
};