[LeetCode]Bulls and Cows

题目地址:https://leetcode.com/problems/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 01 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.

题目描述

题目要求对secret和guess进行比对,找出bull和cow,bull指的是位置相同且字符相同的情况,cow指的是guess中的数在secret中出现过,但是位置不同。

需要特别注意的是多个重复字符的情况,在匹配出一个bull后,那个字符就不能再被cow匹配了,因此需要计数当前还剩下多少个secret字符未被bull匹配。并且bull匹配优先于cow匹配

算法实现

解法一

通过一个secretMap记录出现的字符以及出现次数,先遍历一边guess,找出所有cow,并且记录下所有可能的bull字符。接着对所有可能的bull字符进行遍历,通过查询secretMap判断是否可以匹配。这种方法的效率略低。

class Solution {
public:
    string getHint(string secret, string guess) {
        int acnt = 0; //bull
        int bcnt = 0; //cow
        map<char,int> secretMap;
        vector<char> wrongs;
        int cnt = secret.length();
        for(int i = 0; i < cnt; i++){
            char s = secret[i];
            if(secretMap.find(s) == secretMap.end()){
                secretMap[s] = 1;
            }else{
                secretMap[s]++;
            }
        }
        for(int i = 0; i < cnt; i++){
            char s = secret[i];
            char g = guess[i];
            if(s == g){
                acnt++;
                secretMap[s]--;
            }else{
                wrongs.push_back(g);
            }
        }
        for(int i = 0; i < wrongs.size(); i++){
            char g = wrongs[i];
            if(secretMap[g] > 0){
                secretMap[g]--;
                bcnt++;
            }
        }
        stringstream ss;
        ss << acnt << "A" << bcnt << "B";
        return ss.str();
    }
};


解法二

通过一个count[10]来记录字符0~9的次数,然后遍历secret和guess,如果相同,则匹配为cow。如果不同,则约定每当secret中出现字符s,就把s计数+1;每当guess中出现字符g,就把g计数-1。

这样,当s计数+1,并且发现s的计数≤0,说明有guess中的字符s已经在等待匹配,因此应该把bull计数加一。同理,当g计数-1,并且发现g的计数≥0,说明有secret字符可匹配为bull,也应当把bull计数加一,这种算法比较高效。

class Solution {
public:
    string getHint(string secret, string guess) {
        int acnt = 0; //bull
        int bcnt = 0; //cow
        int count[10];
        memset(count,0,10*sizeof(int));
        vector<char> wrongs;
        int cnt = secret.length();
        for(int i = 0; i < cnt; i++){
            char s = secret[i];
            char g = guess[i];
            if(s == g) acnt++;
            else{
                count[s-'0']++;
                if(count[s-'0']<=0) bcnt++;
                count[g-'0']--;
                if(count[g-'0']>=0) bcnt++;
            }
        }
        stringstream ss;
        ss << acnt << "A" << bcnt << "B";
        return ss.str();
    }
};


posted on 2015-11-02 14:47  张大大123  阅读(187)  评论(0编辑  收藏  举报

导航