2021-9-7 299. Number guessing game (Hash Table + secondary traversal, bucket + primary traversal)

Posted by dzm on Fri, 10 Sep 2021 11:17:57 +0200

Note:

Title:
You are playing balls and cows with your friends. The rules of the game are as follows:

You write a secret number and ask your friend to guess what the number is.
Every time a friend guesses, you will give him a hint to tell him how many digits in the guessed number belong to the number and the exact position are guessed correctly (called "Bulls", bull), and how many digits belong to the number but the position is wrong (called "Cows", cow).
The friend continues to guess according to the hint until he guesses the secret number.
Please write A function that returns A prompt according to the secret number and the guess number of friends. The format of the returned string is xAyB. x and y are numbers, A represents A bull and B represents A cow.

  • xA indicates that there are x digits in the secret number, and the positions are consistent with the secret number.
  • yB indicates that there are y digits in the secret number, but the position is inconsistent with the secret number.
  • Please note that secret numbers and friends' guesses may contain duplicate numbers. Each number can only be counted once.

Example 1:
Input: secret = "1807", guess = "7810"
Output: "1A3B"
Explanation: 1 bull and 3 cows. The bull is 8 and the cow is 0, 1 and 7.
Example 2:
Input: secret = "1123", guess = "0111"
Output: "1A1B"
Explanation: the first 1 in my friend's guess is a bull, and the second or third 1 can be regarded as a cow.

Note: you can assume that both secret numbers and friends' guesses contain only numbers, and their lengths are always equal.

Solution:
Method 1 hash table + secondary traversal
The calculation method is as follows:

  • Bull = same number of characters in the same position
  • Cow = number of characters with the same two substrings - number of bulls

The algorithm flow is:

  1. Count the number of bull numbers whose positions and characters are exactly the same, and establish a hash table for the number of occurrences in secret.
  2. Traverse each number in guass to find the same number of numbers samenum in two strings.
  3. The cow can be obtained by subtracting the number of bull with exactly the same position and character from samenum.

Complexity analysis
Time complexity: O(n)
Space complexity: O(n)

class Solution {
public:
    string getHint(string secret, string guess) {
        map<char,int> times;
        int bulls=0;
        int samenum=0;
        int cows=0;
        string result;
        int size=guess.size();
        for(int i=0;i<size;i++){
            if(secret[i]==guess[i]){
                bulls++;
            }
            times[secret[i]]++;
        }
        for(int i=0;i<size;i++){
            int a=guess[i];
            if(times[a]>0){
                times[a]--;
                samenum++;
            }
        }
        cows=samenum-bulls;
        result+=to_string(bulls);
        result+='A';
        result+=to_string(cows);
        result+='B';
        return result;
    }
};

Method two buckets + one traversal

  1. Since there are only numbers 0-9, bucket[10] is used to store the status of the currently accessed numbers.
  2. Access guess[i] sequentially. If secret[i]==guess[i], then rolls will add 1. Enter the next cycle.
  3. If secret[i]==guess[i], if the current value of bucket[secret[i] - '0'] is less than 0, it means that secret[i] has appeared in guess, and cows is added by one. If the current mapping value of bucket[guess[i] - '0'] is greater than 0, it indicates that guess[i] has appeared in secret, and b will be added automatically.
  4. Access guess[i] to decrease the bucket[guess[i] - [0 '] value by 1, and access secret[i] to increase the bucket[secret[i] - [0'] value by 1.

If you can't understand, you can give an example.

"231" and "321"

secret 2  3  1
guess  3  2  1
       ^
       i

Current traversal to the first number, s = 2, g = 3
numbers[s]++, that is numbers[2] = 1
numbers[g]--, that is numbers[3] = -1    
    
secret 2  3  2
guess  3  2  1
          ^
          i

numbers[2] = 1, numbers[3] = -1
    
Current traversal to the second number, s = 3, g = 2
 here numbers[s], that is numbers[3] < 0, cows++
here numbers[g], that is numbers[2] > 0, cows++
cows = 2

Continue execution
numbers[s]++, that is numbers[3] + 1 = -1 + 1 = 0
numbers[g]--, that is numbers[2] - 1 = 1 - 1 = 0

secret 2  3  2
guess  3  2  1
             ^
             i
numbers[2] = 0, numbers[3] = 0    
Current traversal to the third number, s = 2, g = 1    
here s Although I met two more people, however number[2] = 0 Yes, Can no longer match, therefore cows I won't add 1 

final cows That's 2

Complexity analysis
Time complexity: O(n)
Space complexity: O(n)

class Solution {
public:
    string getHint(string secret, string guess) {
        vector<int> buckets(10);
        int bulls=0;
        int cows=0;
        string result;
        int size=guess.size();
        for(int i=0;i<size;i++){
            if(secret[i]==guess[i]){
                bulls++;
                continue;
            }
            else{
                if(buckets[secret[i]-'0']<0) {
                    cows++;
                }
                if(buckets[guess[i]-'0']>0){
                    cows++;
                }
                buckets[secret[i]-'0']++;
                buckets[guess[i]-'0']--;
            }
        }
        result+=to_string(bulls);
        result+='A';
        result+=to_string(cows);
        result+='B';
        return result;
    }
};

Topics: Algorithm data structure Interview