LeetCode笔记:299. Bulls and Cows

问题:

You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive 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.

大意:

你和你的朋友玩下面这个Bulls and Cows的游戏:你写一个数字,然后问你的朋友去猜数字。每次你的朋友进行一次猜测,你都给他提示说有多少数字是数字与位置都正确的(成为bulls)以及多少数字是数字有但是位置不正确的(成为cows)。你的朋友会根据提示最终猜出数字来。
例子:

秘密数字:“1807”
朋友的猜测:“7810”

提示:1个bull以及3个cows。(bull是8,cows是0,1和7)
写一个函数来根据秘密数字和朋友的额猜测来返回暗示,使用A表示bull,B表示cows。在上面的例子中,你的函数应该返回“1A3B”。
请注意秘密数字和朋友的猜测都可能包含重复的数字,比如:

秘密数字:“1123”
朋友的猜测:“0111”

这种情况下,朋友猜测中的第一个1是bull,第二和第三个1是cow,你的函数应该返回“1A1B”。
你可以假设秘密数字和朋友的猜测都只包含数字,并且长度相等。

思路:

这道题分两步:

第一步找到bull,也就是数字和位置都正确的个数,这个直接循环比对两个字符串同等位置的数字是否一样就好,为了方便我们先全部转换成数组去比较,比较完了记录下个数,还要记录下有哪些位置的数字是bull,这样第二步找cow的时候就不要再判断了。

第二步找cow,再次循环朋友的猜测,这次我们要跳过那些是bull的位置,对不是bull的每一个数字,去循环秘密数字中的数进行判断,判断时要注意第一不能位置一样,第二数字要相等,第三不能是秘密数字中已经是bull的位置。且找到以后除了增加cow数字外也要记录下来在秘密数字中的位置,以后就不要再找了。

在第二次找的过程中要注意我们不能重复找秘密数字中的位置,也就是有一个新数组要记录秘密数字中已经被找到的数字,这时候和bull中的位置是不一样的,所以要另外加一个数组,但是加的时候不能直接等于之前第一步记录的数组来创建,这样在进行修改数组的时候其实还是修改的第一个数组,因为只是引用了一遍位置,要进行深复制,使用clone。

此外对于朋友猜测中的一个数组,只能找一个cow,不能循环找多个,所以找到一个以后直接break退出循环开始找下一个数字。

代码(Java):

public class Solution {
    public String getHint(String secret, String guess) {
        char[] secretArr = secret.toCharArray();
        char[] guessArr = guess.toCharArray();
        int[] bullArr = new int[guess.length()];
        int bull = 0;
        int cow = 0;
        for (int i = 0; i < guessArr.length; i++) {
            if (guessArr[i] == secretArr[i]) {
                bull ++;
                bullArr[i] = 1;
            }
        }
        int[] bullSecretArr = bullArr.clone();
        for (int i = 0; i < guessArr.length; i++) {
            if (bullArr[i] == 0) {
                for (int j = 0; j < secretArr.length; j++) {
                    if (i != j && guessArr[i] == secretArr[j] && bullSecretArr[j] == 0) {
                        cow++;
                        bullSecretArr[j] = 1;
                        break;
                    }
                }
            }
        }
        String result = String.valueOf(bull) + 'A' + String.valueOf(cow) + 'B';
        return result;
    }
}

他山之石:

public class Solution {
    public String getHint(String secret, String guess) {
        int[] a1 = new int[256];
        int[] a2 = new int[256];
        
        int count1 = 0, count2 = 0;
        
        for(int i = 0; i < secret.length(); i++){
            if(secret.charAt(i) == guess.charAt(i)) count1++;
            else{
                a1[secret.charAt(i)]++;
                a2[guess.charAt(i)]++;
            }
        }
        
        for(int i = 0; i < 255; i++){
            if(a1[i] == a2[i]) count2+=a1[i];
            else count2 += Math.min(a1[i],a2[i]);
        }
        
        return count1+"A"+count2+"B";
    }
}

这个做法第一步也是直接找bull,巧妙的地方在于第二步找cow数量的方法。在第一步中对于不是bull的位置的数字,分别都记录下来对应位置的数字,对数字的数量进行累加,这样循环一遍后就知道各自还有哪些数字没找到,以及他们的个数。在找cow的时候,只需要对每个出现过的数字,取两边出现的较少的那一个数量即可,这样也可以避免重复,很巧妙地减少了时间复杂度。

合集:https://github.com/Cloudox/LeetCode-Record


查看作者首页

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容