We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Bulls and Cows

Number: 299

Difficulty: Medium

Paid? No

Companies: Google, Zopsmart, Amazon, Epic Systems, Meta, Adobe


Problem Description

You are given two strings, secret and guess, representing digits. The goal is to return a hint string formatted as "xAyB" where x is the count of bulls—digits in the guess that match the secret in both digit and position—and y is the count of cows—digits in the guess that exist in the secret but are in the wrong position, counting each digit only as many times as it appears (excluding bulls).


Key Insights

  • Use a two-pass approach: the first pass to count bulls (exact matches) and the second pass to handle cows (partial matches among non-bull digits).
  • Maintain frequency counts for unmatched characters from secret and guess to determine the number of cows.
  • For each digit, the number of cows is the minimum between its frequency in secret and guess (ignoring digits already counted as bulls).
  • The cow count must avoid overcounting when duplicates exist in secret or guess.

Space and Time Complexity

Time Complexity: O(n), where n is the length of the input strings. Space Complexity: O(1), as the additional storage is limited to fixed size counters for digits (0-9).


Solution

We iterate through both strings simultaneously. In the first iteration, we identify bulls by checking when characters at the same index are identical. For non-bull positions, we record the frequency of each digit from secret and guess using arrays or hash maps. In a subsequent step, for each digit (0 through 9), we compute cows as the minimum of its count in the secret and guess. Finally, we format the result as "xAyB" providing the count of bulls and cows. This approach efficiently handles duplicate digits and ensures each digit is only counted once in the appropriate category.


Code Solutions

# Python solution for Bulls and Cows

def getHint(secret: str, guess: str) -> str:
    # Initialize counters for bulls and cows
    bulls = 0
    cows = 0
    # Frequency arrays for digits 0-9 in secret and guess (non-bull positions)
    secret_freq = [0] * 10
    guess_freq = [0] * 10

    # First pass: identify bulls and count non-matching digits
    for i in range(len(secret)):
        if secret[i] == guess[i]:
            bulls += 1
        else:
            # Convert digit characters to integers and increment frequency
            secret_freq[int(secret[i])] += 1
            guess_freq[int(guess[i])] += 1

    # Second pass: compute cows from frequency arrays
    for digit in range(10):
        # Cows for each digit are the minimum times it appears in both secret and guess
        cows += min(secret_freq[digit], guess_freq[digit])

    # Format the result as "xAyB" where x is bulls and y is cows
    return f"{bulls}A{cows}B"

# Example usage:
# print(getHint("1807", "7810"))  # Output: "1A3B"
← Back to All Questions