[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();
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章