[LeetCode]52. Bulls and Cows猜数字游戏

You are playing the following Bulls and Cows game with your friend: You write a 4-digit secret number and ask your friend to guess it. Each time your friend guesses a number, you give a hint. The hint tells your friend how many digits are in the correct positions (called "bulls") and how many digits are in the wrong positions (called "cows"). Your friend will use those hints to find out the secret number.

For example:

Secret number:  "1807"
Friend's guess: "7810"

Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.)

Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B".

Please note that both secret number and friend's guess may contain duplicate digits, for example:

Secret number:  "1123"
Friend's guess: "0111"

In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B".

You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.

Credits:
Special thanks to @jeantimex for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

 

解法:有一个四位数字,你猜一个结果,然后根据你猜的结果和真实结果做对比,提示有多少个数字和位置都正确的叫做bulls,还提示有多少数字正确但位置不对的叫做cows。因此我们首先统计猜对了几个数字,然后统计有几个猜对的数字在正确的位置上。

class Solution {
public:
    string getHint(string secret, string guess) {
        int n = secret.size(), bulls = 0, total = 0;
        vector<int> sv(10, 0), gv(10, 0);
        for(int i = 0; i < n; ++i)
        {
            ++sv[secret[i] - '0'];
            ++gv[guess[i] - '0'];
        }
        for(int i = 0; i < 10; ++i)
            total += min(sv[i], gv[i]);

        for(int i = 0; i < n; ++i)
            if(secret[i] == guess[i]) ++bulls;
return to_string(bulls) + 'A' + to_string(total - bulls) + 'B'; } };

上面的解法可以简化:首先在一次循环中找出所有bulls,即数字与位置均正确的个数,同时在这个过程中可以记录下非bulls时secret的分布情况;然后在第二次循环中就可以根据secret的分布情况统计cows的个数了。

class Solution {
public:
    string getHint(string secret, string guess) {
        int n = secret.size(), bulls = 0, cows = 0;
        vector<int> v(10, 0);
        for(int i = 0; i < n; ++i)
        {
            if(guess[i] == secret[i]) ++bulls;
            else ++v[secret[i] - '0']; //注意只在非bulls时才记录
        }
        for(int i = 0; i < n; ++i)
        {
            if(guess[i] != secret[i] && v[guess[i] - '0'] != 0)
            {
                ++cows;
                --v[guess[i] - '0'];
            }
        }
        return to_string(bulls) + "A" + to_string(cows) + "B";
    }
};

再精简,使用一次循环解决。在处理不是bulls的位置时,如果secret当前位置数字的映射值小于0,则表示其在guess中出现过,cows自增1,然后映射值加1,如果guess当前位置的数字的映射值大于0,则表示其在secret中出现过,cows自增1,然后映射值减1。

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

参考:http://www.cnblogs.com/grandyang/p/4929139.html

转载于:https://www.cnblogs.com/aprilcheny/p/4929939.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值